如何从RSAPrivateKey获取RSAPrivateCrtKey? [英] How to get a RSAPrivateCrtKey from a RSAPrivateKey?
问题描述
我有一个java.security.interfaces.RSAPrivateKey和相应的java.security.interfaces.RSAPublicKey,其中包含(仅)模数,私有指数和公共指数。
I have a java.security.interfaces.RSAPrivateKey and the corresponding java.security.interfaces.RSAPublicKey containing (only) modulus, private exponent and public exponent.
如果我理解RSA的权利,那么应该可以恢复java.security.interfaces.RSAPrivateCrtKey的数字(用于CRT密钥)。
If I understand RSA right, it should be possible to recover the numbers for java.security.interfaces.RSAPrivateCrtKey (for CRT keys).
如果是这样,我该怎么办它? (我假设已经有一些实现。)
If so, how do I do it? (I assume there is some implementation already).
推荐答案
可以做到这一点,并且有一种相对较快的算法可以找到参数。这是一些说明该算法的Java代码。
It is possible to do this, and there is a relatively fast algorithm to find the parameters. Here is some Java code that illustrates the algorithm.
/**
* 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) > 0) {
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);
}
这篇关于如何从RSAPrivateKey获取RSAPrivateCrtKey?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!