forked from I2P_Developers/i2p.i2p
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:
@ -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);
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
||||||
/******
|
/******
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Reference in New Issue
Block a user