使用 Java Security 通过模数、公共和私有指数恢复 RSA 私钥 [英] Restore RSA private key by modulus, public and private exponents using Java Security

查看:76
本文介绍了使用 Java Security 通过模数、公共和私有指数恢复 RSA 私钥的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用给定的参数 {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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆