[Webfunds-commits] java/webfunds/sox Crypto.java
Jeroen C. van Gelderen
gelderen@cypherpunks.ai
Wed, 2 Aug 2000 20:59:18 -0400 (AST)
gelderen 00/08/02 20:59:17
Modified: webfunds/sox Crypto.java
Log:
- Use JCE 1.2 keygen with the old RSA encrypt/decrypt routines.
- Cleanup.
I won't write more commit messages until I'm done with this file :-)
Revision Changes Path
1.45 +166 -185 java/webfunds/sox/Crypto.java
Index: Crypto.java
===================================================================
RCS file: /home/webfunds/cvsroot/java/webfunds/sox/Crypto.java,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -r1.44 -r1.45
--- Crypto.java 2000/07/31 18:07:14 1.44
+++ Crypto.java 2000/08/03 00:59:17 1.45
@@ -1,4 +1,4 @@
-/* $Id: Crypto.java,v 1.44 2000/07/31 18:07:14 gelderen Exp $
+/* $Id: Crypto.java,v 1.45 2000/08/03 00:59:17 gelderen Exp $
*
* Copyright (c) Systemics Inc. 1995-2000 on behalf of
* The WebFunds Development Team. All Rights Reserved.
@@ -16,16 +16,17 @@
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
-import java.security.Mode;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
-import java.security.PaddingScheme;
import java.security.PrivateKey;
import java.security.ProviderException;
import java.security.PublicKey;
import java.security.SecureRandom;
+import java.security.Signature;
import java.security.SignatureException;
import java.security.cert.Certificate;
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.security.interfaces.RSAPublicKey;
import java.util.Date;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
@@ -57,7 +58,7 @@
*
* Centralized crypto methods. Currently being overhauled.
*
- * @version $Revision: 1.44 $
+ * @version $Revision: 1.45 $
*/
public final class Crypto
{
@@ -78,22 +79,19 @@
}
- //
- // The default algorithms and the like, which should
- // be overriden at start-up time if desired.
- //
- public static String md_alg = "SHA";
- public static String cipher_alg = "DES-EDE3";
+ private static String
+ CIPHER_ALGORITHM = "DESede",
+ CIPHER_TRANSFORM = "DESede/CBC/PKCS#5",
+ MD_ALGORITHM = "SHA";
+
public static int cipher_keylen = 24;
- public static String cipher_mode = "CBC";
- public static String cipher_padding = "PKCS#5";
public static String pk_alg = "RSA";
- public static int pk_strength = 384; // Testing
public static String sig_alg = "MD5/RSA";
- public static int cert_validity = 365 * 24 * 60 * 60; // a year
- public static boolean quiet = true;
+
+
public static SecureRandom sr;
+
/**
* set a PRNG. Sometimes the default is not good enough.
*/
@@ -123,6 +121,9 @@
+ /**
+ * Global key pair generator. Used by (synchronized) generateKeys only.
+ */
private static KeyPairGenerator keyGen = null;
@@ -137,15 +138,18 @@
logDebug("generateKeys(...)");
try {
if (keyGen == null)
- keyGen = KeyPairGenerator.getInstance(pk_alg);
+ keyGen = KeyPairGenerator.getInstance(pk_alg, "CryptixCrypto");
keyGen.initialize(bits, getSecureRandom());
KeyPair keyPair = keyGen.generateKeyPair();
logDebug("generateKeys: returning " + keyPair);
return keyPair;
- } catch (NoSuchAlgorithmException ex) {
+ } catch(NoSuchAlgorithmException ex) {
throw new ProviderException(pk_alg+" Algorithm missing, " + ex);
+
+ } catch(NoSuchProviderException e) {
+ throw new ProviderException();
}
}
@@ -204,15 +208,15 @@
logDebug("generateKey() called");
try {
KeyGenerator kg =
- KeyGenerator.getInstance("DESede", "CryptixCrypto");
- kg.init(getSecureRandom()); // JCE 1.2
+ KeyGenerator.getInstance(CIPHER_ALGORITHM, "CryptixCrypto");
+ kg.init(getSecureRandom());
Key result = kg.generateKey();
logDebug(result.toString());
return result;
} catch (Exception e) {
throw new ProviderException(
- "Symmetric Algorithm (DESede) not found (" +
+ "Symmetric Algorithm (" + CIPHER_ALGORITHM +") not found (" +
e.getMessage() + ")" );
}
}
@@ -227,23 +231,23 @@
* data (as a byte array)
* The digest uses the algorithm specified in
* crypto.message-digest.algorithm,
- * and if not defined, defaults to the md_alg algorithm.
+ * and if not defined, defaults to the MD_ALGORITHM algorithm.
*
* @param data the data to be digested
* @param offset the offset into the array of the start of the data
* @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) {
+ private static byte[] digest(byte[] data, int offset, int len) {
try {
- MessageDigest md = MessageDigest.getInstance(md_alg);
+ MessageDigest md = MessageDigest.getInstance(MD_ALGORITHM);
md.update(data, offset, len);
return md.digest();
} catch (NoSuchAlgorithmException e) {
- throw new ProviderException("Message digest Algorithm ("+md_alg+
- ") missing ("+e.getMessage()+")");
+ throw new ProviderException("Message digest Algorithm ("+
+ MD_ALGORITHM + ") missing ("+e.getMessage()+")");
}
}
@@ -252,13 +256,12 @@
* data (as a byte array)
* The digest uses the algorithm specified in
* crypto.message-digest.algorithm,
- * and if not defined, defaults to the md_alg algorithm.
+ * and if not defined, defaults to the MD_ALGORITHM algorithm.
*
* @param data the data to be digested
* @return the message digest (as a byte array)
*/
- public static byte[] digest(byte[] data)
- {
+ public static byte[] digest(byte[] data) {
return digest(data, 0, data.length);
}
@@ -277,7 +280,7 @@
* @param len the length of the data with the data array
* @return the encrypted data
*/
- public static byte[] encrypt(Key key, byte[] data, int offset, int len)
+ private static byte[] encrypt(Key key, byte[] data, int offset, int len)
{
logDebug("encrypt() called");
try {
@@ -287,7 +290,7 @@
gzos.finish();
byte[] zipped = baos.toByteArray();
- Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS#5",
+ Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORM,
"CryptixCrypto");
// XXX: IV of all zeroes is a minor security problem
@@ -320,8 +323,7 @@
* @param data the data being encrypted (as a byte array)
* @return the encrypted data
*/
- public static byte[] encrypt(Key key, byte[] data)
- {
+ public static byte[] encrypt(Key key, byte[] data) {
return encrypt(key, data, 0, data.length);
}
@@ -337,12 +339,12 @@
* @return the decrypted data
* @excep KeyException is thrown if the data could not be decrypted
*/
- public static byte[] decrypt(Key key, byte[] data, int offset, int len)
+ private static byte[] decrypt(Key key, byte[] data, int offset, int len)
throws KeyException
{
logDebug("decrypt() called");
try {
- Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS#5",
+ Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORM,
"CryptixCrypto");
// XXX: IV of all zeroes is a minor security problem
@@ -383,9 +385,7 @@
* @param data the data being decrypted (as a byte array)
* @return the decrypted data
*/
- public static byte[] decrypt(Key key, byte[] data)
- throws KeyException
- {
+ public static byte[] decrypt(Key key, byte[] data) throws KeyException {
return decrypt(key, data, 0, data.length);
}
@@ -506,22 +506,6 @@
return pk_encrypt(key, pk, data, 0, data.length);
}
- /**
- * Encrypt the data and return the encrypted binary data.
- * The internal symmetric key is randomly generated.
- *
- * @param pk the PublicKey with which to encrypt the symmetric key
- * @param data the data to be encrypted (as a byte array)
- * @return the encrypted data (as a byte array)
- * @exception KeyException a problem has occurred with the public key,
- * such as it not being in the correct format.
- */
- public static byte[] pk_encrypt(PublicKey pk, byte[] data)
- throws KeyException
- {
- return pk_encrypt(generateKey(), pk, data, 0, data.length);
- }
-
/**
* Decrypt the key portion of a public key encrypted packet.
@@ -533,52 +517,55 @@
* @return the decrypted Key from the data header
* @exception KeyException a problem has occurred with the private key
*/
- public static Key pk_decrypt_key(PrivateKey pk, byte[] data, int offset, int len)
+ private static Key pk_decrypt_key(PrivateKey pk,
+ byte[] data, int offset, int len)
throws KeyException
{
- try {
- //
- // Decrypt the key
- //
- java.security.Cipher rsa =
- java.security.Cipher.getInstance(pk_alg);
- rsa.initDecrypt(pk);
+ pk = translateKey(pk);
+ try {
+ //
+ // Decrypt the key
+ //
+ java.security.Cipher rsa = java.security.Cipher.getInstance(pk_alg);
+ rsa.initDecrypt(pk);
- int pktlen = rsa.getCiphertextBlockSize() + 1;
+ int pktlen = rsa.getCiphertextBlockSize() + 1;
- System.err.println("pktlen: " +pktlen+", data.length: "+data.length);
+ System.err.println("pktlen: "+pktlen+", data.length: "+data.length);
- byte[] rsa_pkt = rsa.crypt(data, offset, pktlen);
- len -= pktlen;
- offset += pktlen;
+ byte[] rsa_pkt = rsa.crypt(data, offset, pktlen);
+ len -= pktlen;
+ offset += pktlen;
- //
- // Unpack the PKCS#1 packet
- //
- if (rsa_pkt[0] != 0)
- throw new KeyException("Bad start of PKCS1 packet in decrypted data");
- if (rsa_pkt[1] != 2)
- throw new KeyException("Bad block type in decrypted data");
-
-
- // Data starts after first zero octet
- int pad_start = 2;
- while(pad_start < rsa_pkt.length && rsa_pkt[pad_start++] != 0)
- ;
- if (pad_start == rsa_pkt.length)
- throw new KeyException("Bad PKCS#1 packet in decrypted data");
-
- byte[] key = new byte[rsa_pkt.length - pad_start];
- if (key.length != cipher_keylen)
- throw new KeyException("Unexpected size of PKCS#1 data field");
-
- System.arraycopy(rsa_pkt, pad_start, key, 0, key.length);
- return new RawSecretKey(cipher_alg, key);
-
- } catch (NoSuchAlgorithmException e) {
- throw new ProviderException(
- pk_alg+" Algorithm not found ("+e.getMessage()+")");
- }
+ //
+ // Unpack the PKCS#1 packet
+ //
+ if (rsa_pkt[0] != 0)
+ throw new KeyException(
+ "Bad start of PKCS1 packet in decrypted data");
+
+ if (rsa_pkt[1] != 2)
+ throw new KeyException("Bad block type in decrypted data");
+
+ // Data starts after first zero octet
+ int pad_start = 2;
+ while(pad_start < rsa_pkt.length && rsa_pkt[pad_start++] != 0)
+ ;
+
+ if (pad_start == rsa_pkt.length)
+ throw new KeyException("Bad PKCS#1 packet in decrypted data");
+
+ byte[] key = new byte[rsa_pkt.length - pad_start];
+ if (key.length != cipher_keylen)
+ throw new KeyException("Unexpected size of PKCS#1 data field");
+
+ System.arraycopy(rsa_pkt, pad_start, key, 0, key.length);
+ return new RawSecretKey(CIPHER_ALGORITHM, key);
+
+ } catch (NoSuchAlgorithmException e) {
+ throw new ProviderException(
+ pk_alg+" Algorithm not found ("+e.getMessage()+")");
+ }
}
/**
@@ -595,25 +582,25 @@
* @return the decrypted Key from the data header
* @exception KeyException a problem has occurred with the private key
*/
- public static byte[] pk_decrypt_data(PrivateKey pk, Key key,
+ private static byte[] pk_decrypt_data(PrivateKey pk, Key key,
byte[] data, int offset, int len)
throws KeyException
{
- try {
- // Only using cipher to get packet length ...
- 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);
- } catch (NoSuchAlgorithmException e) {
- throw new ProviderException(
- pk_alg+" Algorithm not found ("+e.getMessage()+")");
- }
+ pk = translateKey(pk);
+ try {
+ // Only using cipher to get packet length ...
+ 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);
+ } catch (NoSuchAlgorithmException e) {
+ throw new ProviderException(
+ pk_alg+" Algorithm not found ("+e.getMessage()+")");
+ }
}
- /**
+ /**
* Decrypt data, and return the original plaintext
*
* @param pk a PrivateKey with which to decrypt the data
@@ -624,12 +611,12 @@
* @exception KeyException a problem has occurred with the private key,
* such as the password being incorrect.
*/
- public static byte[] pk_decrypt(PrivateKey pk,
+ /*package*/ static byte[] pk_decrypt(PrivateKey pk,
byte[] data, int offset, int len)
throws KeyException
{
- Key key = pk_decrypt_key(pk, data, offset, len);
- return pk_decrypt_data(pk, key, data, offset, len);
+ Key key = pk_decrypt_key(pk, data, offset, len);
+ return pk_decrypt_data(pk, key, data, offset, len);
}
@@ -641,10 +628,10 @@
* @return the decrypted Key from the data header
* @exception KeyException a problem has occurred with the private key
*/
- public static Key pk_decrypt_key(PrivateKey pk, byte[] data)
+ /*package*/ static Key pk_decrypt_key(PrivateKey pk, byte[] data)
throws KeyException
{
- return pk_decrypt_key(pk, data, 0, data.length);
+ return pk_decrypt_key(pk, data, 0, data.length);
}
/**
@@ -658,35 +645,20 @@
* @param data the data to be decrypted (as a byte array)
* @return the decrypted Key from the data header
* @exception KeyException a problem has occurred with the private key
- */
- public static byte[] pk_decrypt_data(PrivateKey pk, Key key, byte[] data)
- throws KeyException
- {
- return pk_decrypt_data(pk, key, data, 0, data.length);
- }
-
- /**
- * Decrypt data, and return the original plaintext
- *
- * @param pk a PrivateKey with which to decrypt the data
- * @param data the data to be decrypted (as a byte array)
- * @return the decrypted data (as a byte array)
- * @exception KeyException a problem has occurred with the private key,
- * such as the password being incorrect.
*/
- public static byte[] pk_decrypt(PrivateKey pk, byte[] data)
+ /*package*/ static byte[] pk_decrypt_data(PrivateKey pk,
+ Key key, byte[] data)
throws KeyException
{
- return pk_decrypt(pk, data, 0, data.length);
+ return pk_decrypt_data(pk, key, data, 0, data.length);
}
-
////////////////////////////////////////////////////////////////////////
// Convenience methods for signing data and verifying the signatures
////////////////////////////////////////////////////////////////////////
- /**
+ /**
* Sign the data and return the binary X509 signature
*
* @param key a PrivateKey with which to sign the data
@@ -695,31 +667,24 @@
* @exception KeyException a problem has occurred with the private key,
* such as the password being incorrect.
*/
- public static byte[] sign(PrivateKey key, byte[] data)
- throws KeyException
- {
- java.security.Signature sig;
- try {
- sig = java.security.Signature.getInstance(sig_alg);
- } catch (NoSuchAlgorithmException e) {
- throw new ProviderException(
- pk_alg+" Algorithm not found ("+e.getMessage()+")");
- }
-
- // Initialise the object with the private key
- sig.initSign(key);
-
- // Update and sign the data
- try {
- sig.update(data);
- return encodeSignature(sig.sign());
- } catch (SignatureException e) {
- throw new InternalError("sign() failed ("+e.getMessage()+")");
- }
+ public static byte[] sign(PrivateKey key, byte[] data) throws KeyException {
+ try {
+ Signature sig = Signature.getInstance(sig_alg);
+ sig.initSign(key);
+ sig.update(data);
+ return encodeSignature(sig.sign());
+
+ } catch (NoSuchAlgorithmException e) {
+ throw new ProviderException(
+ pk_alg+" Algorithm not found ("+e.getMessage()+")");
+
+ } catch (SignatureException e) {
+ throw new InternalError("sign() failed ("+e.getMessage()+")");
+ }
}
- /**
+ /**
* Determine whether the signature on the data is valid
*
* @param key a PublicKey with which to verify the signature
@@ -734,31 +699,21 @@
public static boolean verify(PublicKey key, byte[] sigX509, byte[] data)
throws KeyException
{
- java.security.Signature sig;
- try
- {
- sig = java.security.Signature.getInstance(sig_alg);
- }
- catch (NoSuchAlgorithmException e)
- {
- throw new ProviderException(pk_alg+" Algorithm not found ("+
- e.getMessage()+")");
- }
-
- // Initialise the object with the public key
- sig.initVerify(key);
+ try {
+ Signature sig = Signature.getInstance(sig_alg);
+ sig.initVerify(key);
- // Update and verify the data
- // (remember to convert the X.509 sig to a standard one)
- try
- {
+ // Update and verify the data
+ // (remember to convert the X.509 sig to a standard one)
sig.update(data);
return sig.verify(decodeSignature(sigX509));
- }
- catch (SignatureException e)
- {
+
+ } catch (NoSuchAlgorithmException e) {
+ throw new ProviderException(pk_alg+" Algorithm not found ("+
+ e.getMessage()+")");
+ } catch (SignatureException e) {
e.printStackTrace();
- return false; // Assume that the signature was invalid
+ return false; // Assume that the signature was invalid
}
}
@@ -770,11 +725,10 @@
/**
* Extract the key data (the bitstring) from the X509Key.
*/
- private static byte[] keyData(PublicKey key)
- throws InvalidKeyException
- {
- System.out.println("Fiets!");
+ private static byte[] keyData(PublicKey key) throws InvalidKeyException {
+ logDebug("keyData() called");
+
/*
* The X509Key is defined as:
*
@@ -810,9 +764,8 @@
* @exception InvalidKeyException the X509Key is invalid
* (i.e. incorrectly formatted)
*/
- public static byte[] fingerprint(PublicKey key)
- throws InvalidKeyException
- {
+ public static byte[] fingerprint(PublicKey key) throws InvalidKeyException {
+ key = translateKey(key);
return digest(key.getEncoded());
}
@@ -833,7 +786,7 @@
public static byte[] decodeSignature(byte[] data)
throws SignatureException
{
- System.out.println("Automobiel!");
+
/*
* An X509 signature is defined as:
*
@@ -942,8 +895,9 @@
* @param key The encoded data containing the public key
* @return the encoded key (as a byte array)
*/
- public static byte[] encodePublicKey(PublicKey key)
- {
+ public static byte[] encodePublicKey(PublicKey key) {
+ key = translateKey(key);
+
/*
* An RSA public key is defined as:
*
@@ -1050,6 +1004,7 @@
*/
public static byte[] encodePrivateKey(PrivateKey key)
{
+ key = translateKey(key);
// An RSA private key is defined as:
//
// SEQUENCE {
@@ -1106,21 +1061,47 @@
}
}
+ private static PrivateKey translateKey(PrivateKey key) {
+ if( key.getFormat().equals("Cryptix") ) {
+ RSAPrivateCrtKey rsapk = (RSAPrivateCrtKey)key;
+ return new RawRSAPrivateKey(
+ rsapk.getPrivateExponent(),
+ rsapk.getPrimeP(),
+ rsapk.getPrimeQ(),
+ rsapk.getCrtCoefficient() );
+ }
+ return key;
+ }
+
+
+ private static PublicKey translateKey(PublicKey key) {
+ return toCryptixKey(key);
+ }
+
+
/**
* 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) {
+ public 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.
- */
+ 1G*/
if( pk.getFormat().equals("RAW") )
return pk;
+
+ if( pk.getFormat().equals("Cryptix") ) {
+ RSAPublicKey rsapk = (RSAPublicKey)pk;
+ BigInteger n = rsapk.getModulus();
+ BigInteger e = rsapk.getPublicExponent();
+ return new RawRSAPublicKey(n, e);
+ }
+
try {
AsnInputStream is = new AsnInputStream(pk.getEncoded());