通过模数、public 和使用 Java 安全性的私有指数恢复 RSA 私钥
Restore RSA private key by modulus, public and private exponents using Java Security
我正在尝试找到 Java(本机或 BouncyCastle 提供程序)实现以使用给定参数 {e,n,d} 在 PKCS#1 中生成 RSA 私钥。
Mounir IDRASSI 发布了 paper by Dan Boneh that describes an algorithm for doing so. The solution is available in PyCrypto (Python), as well as there is a standalone utility,可以在 SFM 格式 (n,e,d) 和 CRT 格式 (p,q,dp,dq,u) 之间转换 RSA 密钥,以及其他方式大约。但是我找不到任何准备用于 Java.
的东西
更新:我在 https://github.com/martinpaljak/RSAKeyConverter/blob/master/src/opensc/RSAKeyConverter.java
找到了这样的实现
我在 this 答案中提供了一些代码,我将在此处重现:
/**
* Find a factor of n by following the algorithm outlined in Handbook of Applied Cryptography, section
* 8.2.2(i). See http://cacr.uwaterloo.ca/hac/about/chap8.pdf.
*
*/
private static BigInteger findFactor(BigInteger e, BigInteger d, BigInteger n) {
BigInteger edMinus1 = e.multiply(d).subtract(BigInteger.ONE);
int s = edMinus1.getLowestSetBit();
BigInteger t = edMinus1.shiftRight(s);
for (int aInt = 2; true; aInt++) {
BigInteger aPow = BigInteger.valueOf(aInt).modPow(t, n);
for (int i = 1; i <= s; i++) {
if (aPow.equals(BigInteger.ONE)) {
break;
}
if (aPow.equals(n.subtract(BigInteger.ONE))) {
break;
}
BigInteger aPowSquared = aPow.multiply(aPow).mod(n);
if (aPowSquared.equals(BigInteger.ONE)) {
return aPow.subtract(BigInteger.ONE).gcd(n);
}
aPow = aPowSquared;
}
}
}
public static RSAPrivateCrtKey createCrtKey(RSAPublicKey rsaPub, RSAPrivateKey rsaPriv) throws NoSuchAlgorithmException, InvalidKeySpecException {
BigInteger e = rsaPub.getPublicExponent();
BigInteger d = rsaPriv.getPrivateExponent();
BigInteger n = rsaPub.getModulus();
BigInteger p = findFactor(e, d, n);
BigInteger q = n.divide(p);
if (p.compareTo(q) > 1) {
BigInteger t = p;
p = q;
q = t;
}
BigInteger exp1 = d.mod(p.subtract(BigInteger.ONE));
BigInteger exp2 = d.mod(q.subtract(BigInteger.ONE));
BigInteger coeff = q.modInverse(p);
RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec(n, e, d, p, q, exp1, exp2, coeff);
KeyFactory kf = KeyFactory.getInstance("RSA");
return (RSAPrivateCrtKey) kf.generatePrivate(keySpec);
}
我正在尝试找到 Java(本机或 BouncyCastle 提供程序)实现以使用给定参数 {e,n,d} 在 PKCS#1 中生成 RSA 私钥。
Mounir IDRASSI 发布了 paper by Dan Boneh that describes an algorithm for doing so. The solution is available in PyCrypto (Python), as well as there is a standalone utility,可以在 SFM 格式 (n,e,d) 和 CRT 格式 (p,q,dp,dq,u) 之间转换 RSA 密钥,以及其他方式大约。但是我找不到任何准备用于 Java.
的东西更新:我在 https://github.com/martinpaljak/RSAKeyConverter/blob/master/src/opensc/RSAKeyConverter.java
找到了这样的实现我在 this 答案中提供了一些代码,我将在此处重现:
/**
* Find a factor of n by following the algorithm outlined in Handbook of Applied Cryptography, section
* 8.2.2(i). See http://cacr.uwaterloo.ca/hac/about/chap8.pdf.
*
*/
private static BigInteger findFactor(BigInteger e, BigInteger d, BigInteger n) {
BigInteger edMinus1 = e.multiply(d).subtract(BigInteger.ONE);
int s = edMinus1.getLowestSetBit();
BigInteger t = edMinus1.shiftRight(s);
for (int aInt = 2; true; aInt++) {
BigInteger aPow = BigInteger.valueOf(aInt).modPow(t, n);
for (int i = 1; i <= s; i++) {
if (aPow.equals(BigInteger.ONE)) {
break;
}
if (aPow.equals(n.subtract(BigInteger.ONE))) {
break;
}
BigInteger aPowSquared = aPow.multiply(aPow).mod(n);
if (aPowSquared.equals(BigInteger.ONE)) {
return aPow.subtract(BigInteger.ONE).gcd(n);
}
aPow = aPowSquared;
}
}
}
public static RSAPrivateCrtKey createCrtKey(RSAPublicKey rsaPub, RSAPrivateKey rsaPriv) throws NoSuchAlgorithmException, InvalidKeySpecException {
BigInteger e = rsaPub.getPublicExponent();
BigInteger d = rsaPriv.getPrivateExponent();
BigInteger n = rsaPub.getModulus();
BigInteger p = findFactor(e, d, n);
BigInteger q = n.divide(p);
if (p.compareTo(q) > 1) {
BigInteger t = p;
p = q;
q = t;
}
BigInteger exp1 = d.mod(p.subtract(BigInteger.ONE));
BigInteger exp2 = d.mod(q.subtract(BigInteger.ONE));
BigInteger coeff = q.modInverse(p);
RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec(n, e, d, p, q, exp1, exp2, coeff);
KeyFactory kf = KeyFactory.getInstance("RSA");
return (RSAPrivateCrtKey) kf.generatePrivate(keySpec);
}