【问题标题】:Java RSA Cryptography: RSA modulus has a small prime factorJava RSA 密码学:RSA 模数有一个小的素因数
【发布时间】:2020-01-24 19:23:22
【问题描述】:

尝试使用 RSA 加密消息:我不断收到此错误,但我不确定它的含义:

生成密钥的代码

    generator = KeyPairGenerator.getInstance("RSA");
    RSAKeyGenParameterSpec kpgSpec = new RSAKeyGenParameterSpec(2048, BigInteger.valueOf(17489));
    generator.initialize(kpgSpec);

    KeyPair keyPair = generator.generateKeyPair();

    publicKey = (RSAPublicKey) keyPair.getPublic();
    privateKey = (RSAPrivateKey) keyPair.getPrivate();

加密消息的代码

        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(publicKeyBytes), BigInteger.valueOf(17489));

    Cipher cipher;
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    PublicKey currentKey = (RSAPublicKey) keyFactory.generatePublic(pubKeySpec);
    cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.ENCRYPT_MODE, currentKey);
    byte[] encryptedBytes = cipher.doFinal(data.getBytes());
    encrypted = bytesToString(encryptedBytes);

错误:

W/System.err: java.lang.IllegalArgumentException: RSA modulus has a small prime factor
W/System.err:     at com.android.org.bouncycastle.crypto.params.RSAKeyParameters.validate(RSAKeyParameters.java:46)
    at com.android.org.bouncycastle.crypto.params.RSAKeyParameters.<init>(RSAKeyParameters.java:28)
    at com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa.RSAUtil.generatePublicKeyParameter(RSAUtil.java:44)
    at com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi.engineInit(CipherSpi.java:288)
    at com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi.engineInit(CipherSpi.java:406)

【问题讨论】:

  • 如果您还有这些值,您能否也发布这些值?它们可能很有趣。注意:不要使用它们。
  • 表示您使用第一部分的代码生成的密钥在第二部分的代码中没有使用。

标签: java encryption cryptography rsa public-key-encryption


【解决方案1】:

这是对安全灾难的警告。

在 RSA 中,我们期望复合模数 n 有两个接近于 sqrt{n} 的素数因子*,否则,如果一个素数很小,那么可以很容易地将您的模数因子分解为 @987654332 @ 并驱动你的秘密指数d,BOOM。

再次运行密钥生成器。此外,更喜欢使用公共指数3, 5, 17, 257 or 65537。这有助于更快的计算。您 used 17489 需要 4 次乘法,但 65537 需要 2 - 不计算平方。

另外,你应该打电话

Cipher.getInstance("RSA/ECB/PKCS1Padding");

Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING");

不是

Cipher.getInstance("RSA");

这是不安全的、可塑性强的,并且有很多攻击。

RSA 是一个陷门函数。在加密和签名中,不应该在没有适当填充的情况下使用它。

请注意RSA Signing is Not RSA Decryption

还需要注意的是: 实际上,不推荐使用 RSA 进行加密,一般情况下使用 RSA 进行签名。我们在Hybrid-Cryptosystem 中结合了对称和非对称加密方案。例如,可以使用Diffie-Hellman Key exchangeforward secrecy 建立一个公共密钥,这样就可以使用比任何非对称密码系统都快得多的对称加密算法(如AES)对数据进行加密。还有Key Encapsulation Mechanism(KEM),它适用于RSA,称为RSA-KEM,可用于建立密钥。


*请记住,如果素数彼此太接近,则适用费马分解

【讨论】:

    【解决方案2】:

    要添加到@kelalakas 完整答案,您可以查看导致抛出异常的充气城堡代码here - 相关逻辑是:

        // Hexadecimal value of the product of the 131 smallest odd primes from 3 to 743
    private static final BigInteger SMALL_PRIMES_PRODUCT = new BigInteger(
              "8138e8a0fcf3a4e84a771d40fd305d7f4aa59306d7251de54d98af8fe95729a1f"
            + "73d893fa424cd2edc8636a6c3285e022b0e3866a565ae8108eed8591cd4fe8d2"
            + "ce86165a978d719ebf647f362d33fca29cd179fb42401cbaf3df0c614056f9c8"
            + "f3cfd51e474afb6bc6974f78db8aba8e9e517fded658591ab7502bd41849462f",
        16);
    
    private static final BigInteger ONE = BigInteger.valueOf(1);
    
        if (!modulus.gcd(SMALL_PRIMES_PRODUCT).equals(ONE))
          {
            throw new IllegalArgumentException("RSA modulus has a small prime factor");
          }
    

    因此,查看您的代码,您提供的模数 (new BigInteger(publicKeyBytes)) 与 SMALL_PRIMES_PRODUCT 具有共同因子。

    【讨论】:

    • 很好,而不是除以 131 个最小的素数来查看除以计算 GCD 更有效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-07
    • 1970-01-01
    • 2013-04-12
    • 1970-01-01
    • 2011-07-18
    相关资源
    最近更新 更多