如何从RSAPrivateKey获取RSAPrivateCrtKey?

时间:2017-03-31 08:29:53

标签: java cryptography rsa

我有一个java.security.interfaces.RSAPrivateKey和相应的java.security.interfaces.RSAPublicKey包含(仅)模数,私有指数和公共指数。

如果我理解RSA是正确的,那么应该可以恢复java.security.interfaces.RSAPrivateCrtKey(对于CRT键)的数字。

如果是这样,我该怎么办? (我假设已经有一些实现)。

2 个答案:

答案 0 :(得分:4)

可以这样做,并且有一个相对快速的算法来查找参数。这是一些说明算法的Java代码。

/**
 * 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);

}

答案 1 :(得分:0)

直到我切换到“ <0”,它才起作用。

我通过使用KeyPairGenerator.generateKeyPair()创建密钥对,然后将私钥“按原样”的.getEncoded()与使用keyspec的KeyFactory.generatePrivate()。getEncoded()进行比较来验证了这一点,并得到了相同的结果。