Fix RSA_SHA384

Fix DSAEngine for RSA
   Fix KeyGenerator for RSA
   New split() and combine() methods in SigUtil
   Fix private key conversions for RSA
This commit is contained in:
zzz
2013-09-15 16:49:59 +00:00
parent c6533202f7
commit 79dc95dd66
4 changed files with 54 additions and 44 deletions

View File

@ -491,7 +491,7 @@ public class DSAEngine {
} }
/** /**
* Generic verify DSA_SHA1 or ECDSA * Generic verify DSA_SHA1, ECDSA, or RSA
* @throws GeneralSecurityException if algorithm unvailable or on other errors * @throws GeneralSecurityException if algorithm unvailable or on other errors
* @since 0.9.9 * @since 0.9.9
*/ */
@ -504,7 +504,7 @@ public class DSAEngine {
return altVerifySigSHA1(signature, data, verifyingKey); return altVerifySigSHA1(signature, data, verifyingKey);
java.security.Signature jsig = java.security.Signature.getInstance(type.getAlgorithmName()); java.security.Signature jsig = java.security.Signature.getInstance(type.getAlgorithmName());
PublicKey pubKey = SigUtil.toJavaECKey(verifyingKey); PublicKey pubKey = SigUtil.toJavaKey(verifyingKey);
jsig.initVerify(pubKey); jsig.initVerify(pubKey);
jsig.update(data); jsig.update(data);
boolean rv = jsig.verify(SigUtil.toJavaSig(signature)); boolean rv = jsig.verify(SigUtil.toJavaSig(signature));
@ -569,7 +569,7 @@ public class DSAEngine {
} }
/** /**
* Generic sign DSA_SHA1 or ECDSA * Generic sign DSA_SHA1, ECDSA, or RSA
* @throws GeneralSecurityException if algorithm unvailable or on other errors * @throws GeneralSecurityException if algorithm unvailable or on other errors
* @since 0.9.9 * @since 0.9.9
*/ */
@ -579,7 +579,7 @@ public class DSAEngine {
return altSignSHA1(data, privateKey); return altSignSHA1(data, privateKey);
java.security.Signature jsig = java.security.Signature.getInstance(type.getAlgorithmName()); java.security.Signature jsig = java.security.Signature.getInstance(type.getAlgorithmName());
PrivateKey privKey = SigUtil.toJavaECKey(privateKey); PrivateKey privKey = SigUtil.toJavaKey(privateKey);
jsig.initSign(privKey, _context.random()); jsig.initSign(privKey, _context.random());
jsig.update(data); jsig.update(data);
return SigUtil.fromJavaSig(jsig.sign(), type); return SigUtil.fromJavaSig(jsig.sign(), type);

View File

@ -219,7 +219,7 @@ public class KeyGenerator {
public SimpleDataStructure[] generateSigningKeys(SigType type) throws GeneralSecurityException { public SimpleDataStructure[] generateSigningKeys(SigType type) throws GeneralSecurityException {
if (type == SigType.DSA_SHA1) if (type == SigType.DSA_SHA1)
return generateSigningKeys(); return generateSigningKeys();
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC"); KeyPairGenerator kpg = KeyPairGenerator.getInstance(type.getBaseAlgorithm().getName());
KeyPair kp; KeyPair kp;
try { try {
kpg.initialize(type.getParams(), _context.random()); kpg.initialize(type.getParams(), _context.random());
@ -238,9 +238,9 @@ public class KeyGenerator {
if (!ECConstants.isBCAvailable()) if (!ECConstants.isBCAvailable())
throw new GeneralSecurityException(pname + " KPG failed for " + type, pe); throw new GeneralSecurityException(pname + " KPG failed for " + type, pe);
if (log.shouldLog(Log.WARN)) if (log.shouldLog(Log.WARN))
log.warn(pname + " KPG failed for " + type + ", trying BC", pe); log.warn(pname + " KPG failed for " + type + ", trying BC" /* , pe */ );
try { try {
kpg = KeyPairGenerator.getInstance("EC", "BC"); kpg = KeyPairGenerator.getInstance(type.getBaseAlgorithm().getName(), "BC");
kpg.initialize(type.getParams(), _context.random()); kpg.initialize(type.getParams(), _context.random());
kp = kpg.generateKeyPair(); kp = kpg.generateKeyPair();
} catch (ProviderException pe2) { } catch (ProviderException pe2) {
@ -255,8 +255,8 @@ public class KeyGenerator {
throw new GeneralSecurityException(pname + " KPG for " + type, pe); throw new GeneralSecurityException(pname + " KPG for " + type, pe);
} }
} }
ECPublicKey pubkey = (ECPublicKey) kp.getPublic(); java.security.PublicKey pubkey = kp.getPublic();
ECPrivateKey privkey = (ECPrivateKey) kp.getPrivate(); java.security.PrivateKey privkey = kp.getPrivate();
SimpleDataStructure[] keys = new SimpleDataStructure[2]; SimpleDataStructure[] keys = new SimpleDataStructure[2];
keys[0] = SigUtil.fromJavaKey(pubkey, type); keys[0] = SigUtil.fromJavaKey(pubkey, type);
keys[1] = SigUtil.fromJavaKey(privkey, type); keys[1] = SigUtil.fromJavaKey(privkey, type);
@ -292,7 +292,7 @@ public class KeyGenerator {
public static void main2(String args[]) { public static void main2(String args[]) {
RandomSource.getInstance().nextBoolean(); RandomSource.getInstance().nextBoolean();
try { Thread.sleep(1000); } catch (InterruptedException ie) {} try { Thread.sleep(1000); } catch (InterruptedException ie) {}
int runs = 500; // warmup int runs = 200; // warmup
for (int j = 0; j < 2; j++) { for (int j = 0; j < 2; j++) {
for (int i = 0; i <= 100; i++) { for (int i = 0; i <= 100; i++) {
SigType type = SigType.getByCode(i); SigType type = SigType.getByCode(i);
@ -306,7 +306,7 @@ public class KeyGenerator {
e.printStackTrace(); e.printStackTrace();
} }
} }
runs = 2000; runs = 1000;
} }
} }
@ -331,9 +331,10 @@ public class KeyGenerator {
} }
stime /= 1000*1000; stime /= 1000*1000;
vtime /= 1000*1000; vtime /= 1000*1000;
System.out.println("Sign/verify " + runs + " times: " + (vtime+stime) + " ms = " + System.out.println(type + " sign/verify " + runs + " times: " + (vtime+stime) + " ms = " +
(((double) stime) / runs) + " each sign, " + (((double) stime) / runs) + " each sign, " +
(((double) vtime) / runs) + " each verify"); (((double) vtime) / runs) + " each verify, " +
(((double) (stime + vtime)) / runs) + " s+v");
} }
/****** /******

View File

@ -56,7 +56,7 @@ public enum SigType {
RSA_SHA1(17, 128, 256, 20, 128, SigAlgo.RSA, "SHA-1", "SHA1withRSA", RSAConstants.F4_1024_SPEC), RSA_SHA1(17, 128, 256, 20, 128, SigAlgo.RSA, "SHA-1", "SHA1withRSA", RSAConstants.F4_1024_SPEC),
RSA_SHA256(18, 256, 512, 32, 256, SigAlgo.RSA, "SHA-256", "SHA256withRSA", RSAConstants.F4_2048_SPEC), RSA_SHA256(18, 256, 512, 32, 256, SigAlgo.RSA, "SHA-256", "SHA256withRSA", RSAConstants.F4_2048_SPEC),
RSA_SHA384(19, 384, 768, 48, 384, SigAlgo.RSA, "SHA-384", "SHA2384ithRSA", RSAConstants.F4_3072_SPEC), RSA_SHA384(19, 384, 768, 48, 384, SigAlgo.RSA, "SHA-384", "SHA384withRSA", RSAConstants.F4_3072_SPEC),
RSA_SHA512(20, 512, 1024, 64, 512, SigAlgo.RSA, "SHA-512", "SHA512withRSA", RSAConstants.F4_4096_SPEC), RSA_SHA512(20, 512, 1024, 64, 512, SigAlgo.RSA, "SHA-512", "SHA512withRSA", RSAConstants.F4_4096_SPEC),
//MD5 //MD5

View File

@ -163,16 +163,8 @@ class SigUtil {
private static ECPublicKey cvtToJavaECKey(SigningPublicKey pk) private static ECPublicKey cvtToJavaECKey(SigningPublicKey pk)
throws GeneralSecurityException { throws GeneralSecurityException {
SigType type = pk.getType(); SigType type = pk.getType();
int len = type.getPubkeyLen(); BigInteger[] xy = split(pk.getData());
int sublen = len / 2; ECPoint w = new ECPoint(xy[0], xy[1]);
byte[] b = pk.getData();
byte[] bx = new byte[sublen];
byte[] by = new byte[sublen];
System.arraycopy(b, 0, bx, 0, sublen);
System.arraycopy(b, sublen, by, 0, sublen);
BigInteger x = new NativeBigInteger(1, bx);
BigInteger y = new NativeBigInteger(1, by);
ECPoint w = new ECPoint(x, y);
// see ECConstants re: casting // see ECConstants re: casting
ECPublicKeySpec ks = new ECPublicKeySpec(w, (ECParameterSpec) type.getParams()); ECPublicKeySpec ks = new ECPublicKeySpec(w, (ECParameterSpec) type.getParams());
KeyFactory kf = KeyFactory.getInstance("EC"); KeyFactory kf = KeyFactory.getInstance("EC");
@ -198,12 +190,7 @@ class SigUtil {
BigInteger x = w.getAffineX(); BigInteger x = w.getAffineX();
BigInteger y = w.getAffineY(); BigInteger y = w.getAffineY();
int len = type.getPubkeyLen(); int len = type.getPubkeyLen();
int sublen = len / 2; byte[] b = combine(x, y, len);
byte[] b = new byte[len];
byte[] bx = rectify(x, sublen);
byte[] by = rectify(y, sublen);
System.arraycopy(bx, 0, b, 0, sublen);
System.arraycopy(by, 0, b, sublen, sublen);
return new SigningPublicKey(type, b); return new SigningPublicKey(type, b);
} }
@ -270,21 +257,16 @@ class SigUtil {
} }
/** /**
* @deprecated unimplemented, unused * @deprecated unused
*/ */
public static RSAPrivateKey toJavaRSAKey(SigningPrivateKey pk) public static RSAPrivateKey toJavaRSAKey(SigningPrivateKey pk)
throws GeneralSecurityException { throws GeneralSecurityException {
/*
KeyFactory kf = KeyFactory.getInstance("RSA"); KeyFactory kf = KeyFactory.getInstance("RSA");
// private key is modulus (pubkey) + exponent // private key is modulus (pubkey) + exponent
// get each part like in EC BigInteger[] nd = split(pk.getData());
BigInteger n = new NativeBigInteger(1, ...);
BigInteger d = new NativeBigInteger(1, ...);
// modulus exponent // modulus exponent
KeySpec ks = new RSAPrivateKeySpec(n, d); // 65537 0x10001 KeySpec ks = new RSAPrivateKeySpec(nd[0], nd[1]);
return (RSAPrivateKey) kf.generatePrivate(ks); return (RSAPrivateKey) kf.generatePrivate(ks);
*/
throw new UnsupportedOperationException();
} }
/** /**
@ -299,18 +281,15 @@ class SigUtil {
} }
/** /**
* @deprecated unimplemented, unused * @deprecated unused
*/ */
public static SigningPrivateKey fromJavaKey(RSAPrivateKey pk, SigType type) public static SigningPrivateKey fromJavaKey(RSAPrivateKey pk, SigType type)
throws GeneralSecurityException { throws GeneralSecurityException {
/*
// private key is modulus (pubkey) + exponent // private key is modulus (pubkey) + exponent
BigInteger n = pk.getModulus(); BigInteger n = pk.getModulus();
BigInteger d = pk.getPrivateExponent(); BigInteger d = pk.getPrivateExponent();
// put them together like in EC byte[] b = combine(n, d, type.getPrivkeyLen());
return new SigningPrivateKey(type, bx); return new SigningPrivateKey(type, b);
*/
throw new UnsupportedOperationException();
} }
/** /**
@ -381,6 +360,36 @@ class SigUtil {
} }
} }
/**
* Split a byte array into two BigIntegers
* @return array of two BigIntegers
*/
private static BigInteger[] split(byte[] b) {
int sublen = b.length / 2;
byte[] bx = new byte[sublen];
byte[] by = new byte[sublen];
System.arraycopy(b, 0, bx, 0, sublen);
System.arraycopy(b, sublen, by, 0, sublen);
NativeBigInteger x = new NativeBigInteger(1, bx);
NativeBigInteger y = new NativeBigInteger(1, by);
return new NativeBigInteger[] {x, y};
}
/**
* Combine two BigIntegers of nominal length = len / 2
* @return array of exactly len bytes
*/
private static byte[] combine(BigInteger x, BigInteger y, int len)
throws InvalidKeyException {
int sublen = len / 2;
byte[] b = new byte[len];
byte[] bx = rectify(x, sublen);
byte[] by = rectify(y, sublen);
System.arraycopy(bx, 0, b, 0, sublen);
System.arraycopy(by, 0, b, sublen, sublen);
return b;
}
/** /**
* @param bi non-negative * @param bi non-negative
* @return array of exactly len bytes * @return array of exactly len bytes