Java RSA 密码学:RSA 模数有一个小素因数
Java RSA Cryptography: RSA modulus has a small prime factor
尝试使用 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)
这是对安全灾难的警告。
在RSA中,我们期望复合模数n
有两个接近sqrt{n}
*的质因数,否则如果有一个质数较小则可以轻松地将您的模数计入 n=p q
并驱动您的秘密指数 d
, BOOM.
运行 密钥生成器,再次。此外,更喜欢使用 public 指数 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 是一个陷门函数。在加密和签名中,不应该在没有适当填充的情况下使用它。
- 为了加密,可以使用PKCS1Padding and OAEP。 OAEP是更好的选择。
- 供签名使用RSA-PSS
注意 RSA Signing is Not RSA Decryption.
另请注意:其实并不推荐使用RSA加密,一般情况下都使用RSA进行签名。我们在Hybrid-Cryptosystem. For example, one can use Diffie-Hellman Key exchange to establish a common key with forward secrecy so that the data can be encrypted with a symmetric encryption algorithm like AES which is much faster than any asymmetric cryptosystem. There is, also, Key Encapsulation Mechanism(KEM)中结合了对称和非对称加密方案,适用于RSA,称为RSA-KEM,可用于建立密钥。
*请记住,如果素数彼此太接近,则适用费马因式分解
要添加到@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
有公因数。
尝试使用 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)
这是对安全灾难的警告。
在RSA中,我们期望复合模数n
有两个接近sqrt{n}
*的质因数,否则如果有一个质数较小则可以轻松地将您的模数计入 n=p q
并驱动您的秘密指数 d
, BOOM.
运行 密钥生成器,再次。此外,更喜欢使用 public 指数 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 是一个陷门函数。在加密和签名中,不应该在没有适当填充的情况下使用它。
- 为了加密,可以使用PKCS1Padding and OAEP。 OAEP是更好的选择。
- 供签名使用RSA-PSS
注意 RSA Signing is Not RSA Decryption.
另请注意:其实并不推荐使用RSA加密,一般情况下都使用RSA进行签名。我们在Hybrid-Cryptosystem. For example, one can use Diffie-Hellman Key exchange to establish a common key with forward secrecy so that the data can be encrypted with a symmetric encryption algorithm like AES which is much faster than any asymmetric cryptosystem. There is, also, Key Encapsulation Mechanism(KEM)中结合了对称和非对称加密方案,适用于RSA,称为RSA-KEM,可用于建立密钥。
*请记住,如果素数彼此太接近,则适用费马因式分解
要添加到@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
有公因数。