使用 Java Security 通过模数、公共和私有指数恢复 RSA 私钥 [英] Restore RSA private key by modulus, public and private exponents using Java Security
问题描述
我正在尝试使用给定的参数 {e,n,d} 在 PKCS#1 中找到用于生成 RSA 私钥的 Java(本机或 BouncyCastle 提供程序)实现.
I'm trying to find Java (native or BouncyCastle provider) implementation for generating a RSA private key in PKCS#1 using given params {e,n,d}.
Dan Boneh 撰写的论文描述了一种算法.该解决方案在 PyCrypto (Python) 中可用,还有一个由 Mounir IDRASSI 发布的独立实用程序在 SFM 格式 (n,e,d) 和 CRT 格式 (p,q,dp,dq,u) 之间转换 RSA 密钥,反之亦然.但是我找不到任何可以用于 Java 的东西.
There is 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 posted by Mounir IDRASSI that converts RSA keys between the SFM format (n,e,d) and CRT format (p,q,dp,dq,u), and the other way around. However I was not able to find anything ready to use for Java.
更新:我在 https://github.com/martinpaljak/RSAKeyConverter/blob/master/src/opensc/RSAKeyConverter.java
推荐答案
我在这个答案中提供了一些代码将在这里重现:
I provided some code in this answer which I will reproduce here:
/**
* 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 Security 通过模数、公共和私有指数恢复 RSA 私钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!