我在使模数的大小始终为128字节大时遇到了一些麻烦。有时模数的字节数组的大小为129或甚至130.我已经在线搜索了实现,我的实现非常接近这个链接:http://introcs.cs.princeton.edu/java/78crypto/RSA.java.html
这是我的实施:
public static void genKey() throws NoSuchAlgorithmException, NoSuchProviderException {
int bitLength = 512;
SecureRandom srand = new SecureRandom();
BigInteger one = new BigInteger("1");
BigInteger p = BigInteger.probablePrime(bitLength, srand);
BigInteger q = BigInteger.probablePrime(bitLength, srand);
BigInteger phi = (p.subtract(one)).multiply(q.subtract(one));
BigInteger modulus = p.multiply(q); //Varies here
BigInteger publicKey = new BigInteger("65537");
BigInteger privateKey = publicKey.modInverse(phi);
byte[] modulusArray = modulus.toByteArray();
byte[] publicKeyArray = publicKey.toByteArray();
byte[] privateKeyArray = privateKey.toByteArray();
byte[] tmpArray = new byte[128];
for (int i = 0; i < publicKeyArray.length; i++) {
tmpArray[i] = publicKeyArray[i];
}
publicKeyArray = tmpArray;
byte[] publicKeyAndModulus = concat(modulusArray, publicKeyArray);
byte[] privateKeyAndModulus = concat(modulusArray, privateKeyArray);
}
此外,privateKey长度也会有所不同。我可以使用java.Security库获得更大的一致性,或者这是不是可以实现?
答案 0 :(得分:1)
BigInteger#bitLength()
函数有必要的文档:
返回此BigInteger的最小二进制补码表示中的位数,不包括一个符号位。
当您使用bitLength
512生成BigInteger时,最高有效位将是0到50%的时间,在这种情况下,符号位将取代它的位置,它将适合64个字节,但在在其他情况下,最高有效位将为1,这意味着符号位将被置入一个新字节。
这意味着使用511作为bitLength
总是会产生64字节的BigIntegers和模数的128字节。
您自己不应该真正生成p
,q
,模数和所有其他值。最好使用现有的API,例如Java Cipher类,它也提供与RSA一起使用的适当填充,例如OAEP(PKCS#1 v1.5不再好):&#34; RSA / ECB / OAEPWithSHA-256AndMGF1Padding&#34;
答案 1 :(得分:0)
我建议您使用BouncyCastle并创建AsymmetricCipherKeyPair
;这是我从RSA using BouncyCastle
public static AsymmetricCipherKeyPair generateKeys(int keySizeInBits) {
RSAKeyPairGenerator kpg = new RSAKeyPairGenerator();
kpg.init(new KeyGenerationParameters(new SecureRandom(), keySizeInBits));
return kpg.generateKeyPair();
}