遇到这种问题怎么排查
1.p和q大部分生成的都是正常的。500台中有6台问题。
2.先把n, e, d, p, q, dp, dq, qInv全解出来,与工具解出来的对比一下。查不一致 特别是长度与数据内容。跟正确的对照一下,有什么不一样。
3.发现Qinv长度少一位。用工具试 工具自动加了00,有些工具没加。
4.为什么要用p和q,因为这样快。
使用这个工具可以生成,Bits要填对2048
出现问题的是JAVA代码
下面生成的qInv是127字符。 BigInteger qInv = q.modInverse§; 再转成 RSAPrivateCrtKey rsaKey 再获取rsaKey.getCrtCoefficient().toByteArray() 就是空的。
// 从16进制字符串生成BigInteger
public static BigInteger hexToBigInt(String hex) {
return new BigInteger(hex, 16);
}
// 用p, q生成私钥(e = 65537)
public static PrivateKey generatePrivateKeyFromPQ(String hexP, String hexQ) throws Exception {
Log.d(TAG, "hexP:"+hexP);
Log.d(TAG, "hexQ:"+hexQ);
BigInteger p = hexToBigInt(hexP);
BigInteger q = hexToBigInt(hexQ);
BigInteger n = p.multiply(q); // n = p * q
BigInteger phi = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE));
BigInteger e = BigInteger.valueOf(65537); // 通常使用 65537 作为公钥指数
BigInteger d = e.modInverse(phi); // 私钥指数 d = e^-1 mod φ(n)
BigInteger dp = d.mod(p.subtract(BigInteger.ONE)); // d mod (p - 1)
BigInteger dq = d.mod(q.subtract(BigInteger.ONE)); // d mod (q - 1)
BigInteger qInv = q.modInverse(p); // q^-1 mod p(注意是 q 对 p 的逆)(这里可能需要补00)
RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec(
n, e, d, p, q, dp, dq, qInv
);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(keySpec);
}
我补0后 正确
private int loadRsaPair2(String hexP, String hexQ) throws Exception
{
Log.d(TAG,"hexP:"+hexP);
Log.d(TAG,"hexQ:"+hexQ);
BigInteger p = hexToBigInt(hexP);
BigInteger q = hexToBigInt(hexQ);
BigInteger n = p.multiply(q); // n = p * q
BigInteger phi = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE));
BigInteger e = BigInteger.valueOf(65537); // 通常使用 65537 作为公钥指数
BigInteger d = e.modInverse(phi); // 私钥指数 d = e^-1 mod φ(n)
BigInteger dp2 = d.mod(p.subtract(BigInteger.ONE)); // d mod (p - 1)
BigInteger dq2 = d.mod(q.subtract(BigInteger.ONE)); // d mod (q - 1)
BigInteger qInv = q.modInverse(p); // q^-1 mod p(注意是 q 对 p 的逆)
RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec(
n, e, d, p, q, dp2, dq2, qInv
);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) keyFactory.generatePrivate(keySpec);
int bits = rsaKey.getModulus().bitLength();
int exponent = rsaKey.getPublicExponent().intValue();
showText("bits:" + bits + " exponent: " + exponent);
int length = bits / 8;
byte[] modulus = copyArrays(rsaKey.getModulus().toByteArray(), length);
byte[] primeP = copyArrays(rsaKey.getPrimeP().toByteArray(), length / 2);
byte[] primeQ = copyArrays(rsaKey.getPrimeQ().toByteArray(), length / 2);
byte[] dp = copyArrays(rsaKey.getPrimeExponentP().toByteArray(), length / 2);
byte[] dq = copyArrays(rsaKey.getPrimeExponentQ().toByteArray(), length / 2);
// byte[] invQ = copyArrays(rsaKey.getCrtCoefficient().toByteArray(), length / 2);
byte[] invQ=new byte[128];
byte[] temp =qInv.toByteArray();
System.arraycopy(temp, 0, invQ, invQ.length-temp.length,temp.length);
Log.d(TAG, "modulus: "+BytesUtils.bytesToString(modulus));
Log.d(TAG, "primeP: "+BytesUtils.bytesToString(primeP));
Log.d(TAG, "primeQ: "+BytesUtils.bytesToString(primeQ));
Log.d(TAG, "dp: "+BytesUtils.bytesToString(dp));
Log.d(TAG, "dq: "+BytesUtils.bytesToString(dq));
Log.d(TAG, "invQ: "+BytesUtils.bytesToString(invQ));
int ret = ikey.setKeyGroupName("ftsafe_internal_group");
if (ret != ErrCode.ERR_SUCCESS) {
showText("Set keyGroup name error : " + ret + " " + ErrCode.toString(ret));
return ret;
}
ret = ikey.loadRsaKeyPair(
KeyType.KEY_TYPE_RSA,
9, //固定值
bits,
modulus,
exponent,
primeP,
primeQ,
dp,
dq,
invQ
);
if (ret != ErrCode.ERR_SUCCESS) {
showText("Load RsaKeyPair error : " + ret + " " + ErrCode.toString(ret));
return ret;
}
return ErrCode.ERR_SUCCESS;
}
// 从16进制字符串生成BigInteger
public static BigInteger hexToBigInt(String hex) {
return new BigInteger(hex, 16);
}