当前位置: 首页 > 知识库问答 >
问题:

使用Java安全性按模数、公有和私有指数还原RSA私钥

闻人升
2023-03-14

我试图找到Java(本机或BouncyCastle提供程序)实现,以使用给定的参数{e,n,d}在PKCS#1中生成RSA私钥。

Dan Boneh的一篇论文描述了这样做的算法。PyCrypto(Python)提供了该解决方案,并且Mounir IDRASSI发布了一个独立的实用程序,用于在SFM格式(n,e,d)和CRT格式(p,q,dp,dq,u)之间转换RSA密钥,或者相反。然而,我无法找到任何可用于Java的东西。

更新:我在https://github.com/martinpaljak/rsakeyconverter/blob/master/src/opensc/rsakeyconverter.java找到了这样的实现

共有1个答案

徐高韵
2023-03-14

我在这个答案中提供了一些代码,我将在这里重现:

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

}
 类似资料:
  • 我也尝试了npm ursa模块,不幸的是没有成功。

  • 我一直在阅读一些RSA文献和堆栈溢出问题,但我没有得到明确的答案。 仅给定一个RSA私钥模和私钥指数,这是我所拥有的全部(也足够用于所有密码相关操作),我能得到相关的公钥模和公钥指数吗? 另外,我是否可以仅用这两个参数获得私钥的编码形式?我在java中尝试了以下方法(java不是实际的请求),但是支持它的OpenSSL引擎失败,错误为:04000090:RSA例程:openSSL_internal

  • 我想解密使用RSA公钥加密的1024位数据。我有权访问 我没有访问私钥指数的权限。没有RSA private exponent和所有这些可用的API,有没有办法解密数据?我正在使用openssl进行RSA操作。我听说有了中文提示therem,我们只需要p、q、指数1、指数2和系数就可以进行RSA解密。但我正在寻找openssl中的API。在openssl中有没有什么有用的方法可以在没有私有指数的情

  • 我试图从模数&私有/公共指数重建一个RSA keypair。对公钥的转换是正确的,但对私钥的转换在比较编码的私钥时失败。 当使用此重建私有/公共键盘进行加密时,它工作(!)在Java中,但是在PHP中使用rebuild keypair时,解密部分失败(加密工作),所以在我看来,rebuild私钥与“原始”私钥是不同的。 仅供参考:使用“原始”keypair在PHP中一切都很好。 所以我的问题是:如

  • 本书之前提到了“封装”的概念,即指将一系列指令放在一个函数体内部的处理过程。而这样的做法则是为了将函数的接口与它的实现分离(函数接口指如何使用这个函数,函数实现则指如何去实现这个函数及实现具体做了些什么)。 上面提到这种封装可以命名为“功能封装”,用以区分本章将要介绍的“数据封装”。数据封装是基于这样的理念提出的:每一个结构的定义应当包括应用于本结构的函数集以及阻止对内部的无限制访问。 数据封装的

  • 主要的问题是,我对C相当陌生,OpenSSL留档对我来说不够清晰,我尝试过使用读和写rsa键到C中的pem文件,但我不太明白。例如,函数如何创建私有和公共?而从何而来?pcszPassphrase的意义是什么? 我会解释,好像这是某种伪代码,这就是我想做的,粗体部分是我不知道如何做的: 生成私钥和公钥作为十六进制缓冲区(客户端) 基本上,我知道如何处理AES加密/解密和通信协议,反正他们已经实现了