Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: mindbright/util/EncryptedProperties.java


1   /******************************************************************************
2    *
3    * Copyright (c) 1998,99 by Mindbright Technology AB, Stockholm, Sweden.
4    *                 www.mindbright.se, info@mindbright.se
5    *
6    * This program is free software; you can redistribute it and/or modify
7    * it under the terms of the GNU General Public License as published by
8    * the Free Software Foundation; either version 2 of the License, or
9    * (at your option) any later version.
10   *
11   * This program is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU General Public License for more details.
15   *
16   *****************************************************************************
17   * $Author: nallen $
18   * $Date: 2001/11/12 16:31:29 $
19   * $Name:  $
20   *****************************************************************************/
21  package mindbright.util;
22  
23  import java.io.InputStream;
24  import java.io.OutputStream;
25  import java.io.ByteArrayOutputStream;
26  import java.io.ByteArrayInputStream;
27  import java.io.IOException;
28  import java.util.Properties;
29  import java.util.Enumeration;
30  
31  import mindbright.security.*;
32  
33  public class EncryptedProperties extends Properties {
34      public final static String HASH_KEY     = "EncryptedProperties.hash";
35      public final static String CIPHER_KEY   = "EncryptedProperties.cipher";
36      public final static String CONTENTS_KEY = "EncryptedProperties.contents";
37      public final static String SIZE_KEY     = "EncryptedProperties.size";
38      public final static String PROPS_HEADER = "Sealed with mindbright.util.EncryptedProperties" +
39    "(ver. $Name:  $" + "$Date: 2001/11/12 16:31:29 $)";
40  
41      private boolean isNormalPropsFile;
42  
43      public EncryptedProperties() {
44    super();
45    isNormalPropsFile = false;
46      }
47  
48      public EncryptedProperties(Properties defaultProperties) {
49    super(defaultProperties);
50    isNormalPropsFile = false;
51      }
52  
53      public boolean isNormalPropsFile() {
54    return isNormalPropsFile;
55      }
56  
57      public synchronized void save(OutputStream out, String header, String password,
58            String cipherName) throws IOException {
59    ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
60    Properties            encProps = new Properties();
61    byte[]                contents, hash;
62    String                hashStr;
63    Cipher                cipher = Cipher.getInstance(cipherName);
64    int                   size;
65  
66    if(cipher == null)
67        throw new IOException("Unknown cipher '" + cipherName + "'");
68  
69    save(bytesOut, header);
70  
71    contents = bytesOut.toByteArray();
72    size = contents.length;
73    try {
74        MessageDigest md5 = MessageDigest.getInstance("MD5");
75        md5.update(contents);
76        hash = md5.digest();
77    } catch(Exception e) {
78        throw new IOException("MD5 not implemented, can't generate session-id");
79    }
80  
81    hash    = Base64.encode(hash);
82    hashStr = new String(hash);
83  
84    // Assume cipher-block length no longer than 8
85    //
86    byte[] tmp = new byte[contents.length + (8 - (contents.length % 8))];
87    System.arraycopy(contents, 0, tmp, 0, contents.length);
88    contents = new byte[tmp.length];
89  
90    cipher.setKey(hashStr + password);
91    cipher.encrypt(tmp, 0, contents, 0, contents.length);
92  
93    contents = Base64.encode(contents);
94  
95    encProps.put(HASH_KEY, new String(hash));
96    encProps.put(CIPHER_KEY, cipherName);
97    encProps.put(CONTENTS_KEY, new String(contents));
98    encProps.put(SIZE_KEY, String.valueOf(size));
99    encProps.save(out, PROPS_HEADER);
100   out.flush();
101     }
102 
103     public synchronized void load(InputStream in, String password) throws IOException, AccessDeniedException {
104   Properties encProps = new Properties();
105   String     hashStr, cipherName, contentsStr, sizeStr;
106   byte[]     contents, hash, hashCalc;
107   Cipher     cipher;
108   int        size;
109 
110   encProps.load(in);
111 
112   hashStr     = encProps.getProperty(HASH_KEY);
113   cipherName  = encProps.getProperty(CIPHER_KEY);
114   contentsStr = encProps.getProperty(CONTENTS_KEY);
115   sizeStr     = encProps.getProperty(SIZE_KEY);
116 
117   // Assume normal properties if our keys are not found (i.e. for
118   // "backwards compatible" reading of properties which will be encrypted
119   // if saved)
120   //
121   if(hashStr == null && cipherName == null && contentsStr == null && sizeStr == null) {
122       isNormalPropsFile = true;
123       Enumeration keys = encProps.keys();
124       while(keys.hasMoreElements()) {
125     String key = (String)keys.nextElement();
126     put(key, encProps.getProperty(key));
127       }
128       return;
129   }
130 
131   size = Integer.parseInt(sizeStr);
132 
133   hash     = Base64.decode(hashStr.getBytes());
134   contents = Base64.decode(contentsStr.getBytes());
135 
136   cipher = Cipher.getInstance(cipherName);
137   if(cipher == null)
138       throw new IOException("Unknown cipher '" + cipherName + "'");
139 
140   cipher.setKey(hashStr + password);
141   cipher.decrypt(contents, 0, contents, 0, contents.length);
142 
143   byte[] tmp = new byte[size];
144   System.arraycopy(contents, 0, tmp, 0, size);
145   contents = tmp;
146 
147   try {
148       MessageDigest md5 = MessageDigest.getInstance("MD5");
149       md5.update(contents);
150       hashCalc = md5.digest();
151   } catch(Exception e) {
152       throw new IOException("MD5 not implemented, can't generate session-id");
153   }
154 
155   for(int i = 0; i < hash.length; i++) {
156       if(hash[i] != hashCalc[i])
157     throw new AccessDeniedException("Access denied");
158   }
159 
160   ByteArrayInputStream bytesIn = new ByteArrayInputStream(contents);
161   load(bytesIn);
162     }
163 
164     /* !!! DEBUG
165     public static void main(String[] argv) {
166   EncryptedProperties test = new EncryptedProperties();
167 
168   test.put("Foo", "bar");
169   test.put("foo", "bAR");
170   test.put("bar", "FOO");
171   test.put("BAR", "foo");
172 
173   try {
174       test.save(new java.io.FileOutputStream("/tmp/fooprops"), "These are some meaningless props...",
175           "foobar", "Blowfish");
176       test = new EncryptedProperties();
177       test.load(new java.io.FileInputStream("/tmp/fooprops"), "foobar");
178 
179       System.out.println("test: " + test.getProperty("BAR") + test.getProperty("Foo"));
180 
181   } catch (Exception e) {
182       System.out.println("Error:" + e);
183       e.printStackTrace();
184   }
185     }
186     */
187 
188 }