[Webfunds-commits] java/webfunds/sox Crypto.java
Jeroen C. van Gelderen
gelderen@cypherpunks.ai
Sat, 29 Jul 2000 23:59:59 -0400 (AST)
gelderen 00/07/29 23:59:59
Modified: webfunds/sox Crypto.java
Log:
Checkpoint.
- Remove unused password-based encryption functions for now.
They were insecure and needed be replaced anyway.
- Same for secure checksum routines.
- Use JCE KeyGenerator for TripleDES keys.
- Add some basic debugging methods and calls. Will be improved upon.
- Remove import of java.security.Cipher and change all uses of Cipher to
use fully qualified class names. This is neccessary to prevent name
clashes with JCE and will go away soon.
- Load CryptixCrypto (JCE) provider dynamically.
- Make generateKeys(...) synchronized because of potential race conditions.
Revision Changes Path
1.41 +80 -215 java/webfunds/sox/Crypto.java
Index: Crypto.java
===================================================================
RCS file: /home/webfunds/cvsroot/java/webfunds/sox/Crypto.java,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -r1.40 -r1.41
--- Crypto.java 2000/07/29 17:15:33 1.40
+++ Crypto.java 2000/07/30 03:59:58 1.41
@@ -1,4 +1,4 @@
-/* $Id: Crypto.java,v 1.40 2000/07/29 17:15:33 gelderen Exp $
+/* $Id: Crypto.java,v 1.41 2000/07/30 03:59:58 gelderen Exp $
*
* Copyright (c) Systemics Inc. 1995-2000 on behalf of
* The WebFunds Development Team. All Rights Reserved.
@@ -8,12 +8,10 @@
import java.io.*;
import java.math.BigInteger;
-import java.security.Cipher;
import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyException;
-import java.security.KeyGenerator;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
@@ -30,6 +28,8 @@
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
+import javax.crypto.KeyGenerator;
+
import cryptix.provider.key.RawSecretKey;
import cryptix.provider.rsa.RawRSAPrivateKey;
import cryptix.provider.rsa.RawRSAPublicKey;
@@ -50,13 +50,24 @@
*
* Centralized crypto methods. Currently being overhauled.
*
- * @version $Revision: 1.40 $
+ * @version $Revision: 1.41 $
*/
public final class Crypto
{
- static
- {
+
+// Debug helper methods
+//............................................................................
+
+ private static void logDebug(String s) {
+ System.err.println("Crypto: " + s);
+ }
+
+//............................................................................
+
+ static {
java.security.Security.addProvider(new cryptix.provider.Cryptix());
+ java.security.Security.addProvider(
+ new cryptix.jce.provider.CryptixCrypto() );
}
@@ -104,29 +115,31 @@
}
+
+ private static KeyPairGenerator keyGen = null;
- protected static KeyPairGenerator keyGen = null;
/**
* Useful for making accounts, better than certs.
* Do this:
* PublicKey publicKey = keyPair.getPublic();
- * privateKey = keyPair.getPrivate();
+ * PrivateKey privateKey = keyPair.getPrivate();
*/
- public static KeyPair generateKeys(int bits)
+ public static synchronized KeyPair generateKeys(int bits)
{
- if (keyGen == null)
- {
- try {
+ logDebug("generateKeys(...)");
+ try {
+ if (keyGen == null)
keyGen = KeyPairGenerator.getInstance(pk_alg);
- } catch (NoSuchAlgorithmException ex) {
- throw new ProviderException(pk_alg+" Algorithm missing, " + ex);
- }
- }
- keyGen.initialize(bits, getSecureRandom());
- KeyPair keyPair = keyGen.generateKeyPair();
- return keyPair;
+ keyGen.initialize(bits, getSecureRandom());
+ KeyPair keyPair = keyGen.generateKeyPair();
+ logDebug("generateKeys: returning " + keyPair);
+ return keyPair;
+
+ } catch (NoSuchAlgorithmException ex) {
+ throw new ProviderException(pk_alg+" Algorithm missing, " + ex);
+ }
}
@@ -175,59 +188,26 @@
* Generate (randomly) a new Key object,
* suitable for the default symmetric cipher.
*
+ * Uses JCE 1.2.
+ *
* @return A new (random) Key object
*/
- public static Key generateKey()
- throws KeyException
- {
- try {
- // if (sr == null)
- // sr = new SecureRandom();
-
- //
- // This is the JCE 1.2 way of generating a symmetric key
- //
- KeyGenerator kg = KeyGenerator.getInstance(cipher_alg);
- // kg.init(getSecureRandom()); // JCE 1.2
- kg.initialize(getSecureRandom()); // JCE 1.1
- return kg.generateKey();
- } catch (NoSuchAlgorithmException e) {
- throw new ProviderException("Symmetric Algorithm (" + cipher_alg +
- ") not found ("+ e.getMessage()+")");
- }
- }
+ public static Key generateKey() throws KeyException {
- /**
- * Turn a password into a key of <i>n</i> bytes,
- * suitable for use with a symmetric cipher
- * This is achieved by running the password through
- * a message digest function, and using procrastean
- * assignment to the return value.
- * @param password the password being converted
- * @return the key
- */
- public static Key password2key(String password)
- {
- MessageDigest md;
+ logDebug("generateKey() called");
try {
- md = MessageDigest.getInstance(md_alg);
- }
- catch (NoSuchAlgorithmException e) {
- throw new InternalError("Badly installed JCE: missing Algorithm ("+
- e.getMessage()+")");
- }
- md.update(password.getBytes());
- byte[] digest = md.digest();
- byte[] key = new byte[cipher_keylen];
- int pos = 0;
- while (pos < cipher_keylen) {
- int count = digest.length;
- if ((pos + count) > cipher_keylen)
- count = cipher_keylen - pos;
- System.arraycopy(digest, 0, key, pos, count);
- pos += count;
+ KeyGenerator kg =
+ KeyGenerator.getInstance("DESede", "CryptixCrypto");
+ kg.init(getSecureRandom()); // JCE 1.2
+ Key result = kg.generateKey();
+ logDebug(result.toString());
+ return result;
+
+ } catch (Exception e) {
+ throw new ProviderException(
+ "Symmetric Algorithm (DESede) not found (" +
+ e.getMessage() + ")" );
}
- return new RawSecretKey(cipher_alg, key);
}
@@ -247,18 +227,17 @@
* @param len the length of the data
* @return the message digest (as a byte array)
*/
- public static byte[] digest(byte[] data, int offset, int len)
- {
- MessageDigest md;
+ public static byte[] digest(byte[] data, int offset, int len) {
+
try {
- md = MessageDigest.getInstance(md_alg);
- }
- catch (NoSuchAlgorithmException e) {
+ MessageDigest md = MessageDigest.getInstance(md_alg);
+ md.update(data, offset, len);
+ return md.digest();
+
+ } catch (NoSuchAlgorithmException e) {
throw new ProviderException("Message digest Algorithm ("+md_alg+
") missing ("+e.getMessage()+")");
}
- md.update(data, offset, len);
- return md.digest();
}
/**
@@ -277,66 +256,6 @@
}
-
-////////////////////////////////////////////////////////////////////////
-// Convenience methods for getting secure checksums of data
-////////////////////////////////////////////////////////////////////////
-
- /**
- * Create a secure checksum (as a byte array) from some data.
- * This checksum can be used to "lock" some data, in order to
- * prevent tampering. This is achieved by saving this secure
- * checksum along with the data, and in the future when the
- * data is restored, the checksum should again be computed and
- * compared with the stored checksum. Without knowledge of the
- * secret password, it is infeasible for the data to be modified
- * and the checksum adjusted to hide the fact that the modification
- * has taken place.
- *
- * @param password the secret with which to secure the checksum
- * @param data the data to be checksummed
- * @param offset the offset into the array of the start of the data
- * @param len the length of the data
- * @return the secure checksum (as a byte array)
- */
- public static byte[] checksum(String password,
- byte[] data, int offset, int len)
- {
- MessageDigest md;
- try {
- md = MessageDigest.getInstance(md_alg);
- }
- catch (NoSuchAlgorithmException e) {
- throw new ProviderException("Message digest Algorithm ("+md_alg+
- ") missing ("+e.getMessage()+")");
- }
- md.update(password.getBytes());
- md.update(data, offset, len);
- return md.digest();
- }
-
- /**
- * Create a secure checksum (as a byte array) from some data.
- * This checksum can be used to "lock" some data, in order to
- * prevent tampering. This is achieved by saving this secure
- * checksum along with the data, and in the future when the
- * data is restored, the checksum should again be computed and
- * compared with the stored checksum. Without knowledge of the
- * secret password, it is infeasible for the data to be modified
- * and the checksum adjusted to hide the fact that the modification
- * has taken place.
- *
- * @param password the secret with which to secure the checksum
- * @param data the data to be checksummed
- * @return the secure checksum (as a byte array)
- */
- public static byte[] checksum(String password, byte[] data)
- {
- return checksum(password, data, 0, data.length);
- }
-
-
-
////////////////////////////////////////////////////////////////////////
// Convenience methods for symmetric cipher encrypting and decrypting
////////////////////////////////////////////////////////////////////////
@@ -353,12 +272,12 @@
*/
public static byte[] encrypt(Key key, byte[] data, int offset, int len)
{
-
try {
- Cipher cipher = Cipher.getInstance(Cipher.getInstance(cipher_alg),
- (Mode)Mode.getInstance(cipher_mode),
- PaddingScheme.getInstance(cipher_padding)
- );
+ java.security.Cipher cipher =
+ java.security.Cipher.getInstance(
+ java.security.Cipher.getInstance(cipher_alg),
+ (Mode)Mode.getInstance(cipher_mode),
+ PaddingScheme.getInstance(cipher_padding) );
ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -389,25 +308,7 @@
}
-
- /**
- * Encrypt the data and return the encrypted binary data
- * The data is compressed before encrypting
- *
- * @param password the password with which to encrypt the data
- * @param data the data being encrypted (as a byte array)
- * @param offset the offset within <i>data</i> from which to start
- * @param len the length of the data with the <i>data</i> array
- * @return the encrypted data
- */
- public static byte[] encrypt(String password,
- byte[] data, int offset, int len)
- {
- return encrypt(password2key(password), data, offset, len);
- }
-
-
- /**
+ /**
* Encrypt the data and return the encrypted binary data
* The data is compressed before encrypting
*
@@ -420,20 +321,7 @@
return encrypt(key, data, 0, data.length);
}
- /**
- * Encrypt the data and return the encrypted binary data
- * The data is compressed before encrypting
- *
- * @param password the password with which to encrypt the data
- * @param data the data being encrypted (as a byte array)
- * @return the encrypted data
- */
- public static byte[] encrypt(String password, byte[] data)
- {
- return encrypt(password2key(password), data, 0, data.length);
- }
-
/**
* Decrypt the data and return the decrypted binary data
* The data is decompressed after decrypting
@@ -448,14 +336,13 @@
public static byte[] decrypt(Key key, byte[] data, int offset, int len)
throws KeyException
{
-
- try
- {
-
- Cipher cipher = Cipher.getInstance(Cipher.getInstance(cipher_alg),
- (Mode)Mode.getInstance(cipher_mode),
- PaddingScheme.getInstance(cipher_padding)
- );
+ try {
+ java.security.Cipher cipher =
+ java.security.Cipher.getInstance(
+ java.security.Cipher.getInstance(cipher_alg),
+ (Mode)Mode.getInstance(cipher_mode),
+ PaddingScheme.getInstance(cipher_padding) );
+
cipher.initDecrypt(key);
int zippedLen = cipher.doFinal(data, offset, len, data, 0);
@@ -489,22 +376,6 @@
}
}
- /**
- * Decrypt the data and return the encrypted binary data
- * The data is uncompressed after decrypting
- *
- * @param password the password with which to decrypt the data
- * @param data the data being decrypted (as a byte array)
- * @param offset the offset within <i>data</i> from which to start
- * @param len the length of the data with the <i>data</i> array
- * @return the decrypted data
- */
- public static byte[] decrypt(String password,
- byte[] data, int offset, int len)
- throws KeyException
- {
- return decrypt(password2key(password), data, offset, len);
- }
/**
* Decrypt the data and return the encrypted binary data
@@ -520,22 +391,7 @@
return decrypt(key, data, 0, data.length);
}
- /**
- * Decrypt the data and return the encrypted binary data
- * The data is uncompressed after decrypting
- *
- * @param password the password with which to decrypt the data
- * @param data the data being decrypted (as a byte array)
- * @return the decrypted data
- */
- public static byte[] decrypt(String password, byte[] data)
- throws KeyException
- {
- return decrypt(password2key(password), data);
- }
-
-
////////////////////////////////////////////////////////////////////////
// Convenience methods for asymmetric cipher encrypting and decrypting
////////////////////////////////////////////////////////////////////////
@@ -560,7 +416,8 @@
// if (sr == null)
// sr = new SecureRandom();
- Cipher rsa = Cipher.getInstance(pk_alg);
+ java.security.Cipher rsa =
+ java.security.Cipher.getInstance(pk_alg);
pk = toCryptixKey(pk);
rsa.initEncrypt(pk);
@@ -691,7 +548,8 @@
//
// Decrypt the key
//
- Cipher rsa = Cipher.getInstance(pk_alg);
+ java.security.Cipher rsa =
+ java.security.Cipher.getInstance(pk_alg);
rsa.initDecrypt(pk);
int pktlen = rsa.getCiphertextBlockSize() + 1;
@@ -751,7 +609,8 @@
{
try {
// Only using cipher to get packet length ...
- Cipher rsa = Cipher.getInstance(pk_alg);
+ java.security.Cipher rsa =
+ java.security.Cipher.getInstance(pk_alg);
rsa.initDecrypt(pk);
int pktlen = rsa.getCiphertextBlockSize();
return decrypt(key, data, offset+pktlen, len-pktlen);
@@ -1256,8 +1115,14 @@
}
- // XXX: move out of Certificate.java. Can go for JCE 1.2
+ /**
+ * Convert the given key to a Cryptix' RawRSAPublicKey.
+ *
+ * <p>This is a no-op when the given key already is RawRSAPublicKey.</p>
+ */
private static PublicKey toCryptixKey(PublicKey pk) {
+
+ // XXX: move out of Certificate.java. Can go for JCE 1.2
/*
* Don't do conversion when the key is a Cryptix RAW-encoded key.