[英]Different encryption Android vs pure Java - RSA/ECB/OAEPWithMD5AndMGF1Padding
I encrypt a string in Android by the public key.我用公钥加密了 Android 中的一个字符串。 However, I get an exception "Decryption error" when I try to decrypt the encrypted string by the private key in pure Java code.
但是,当我尝试通过纯 Java 代码中的私钥解密加密字符串时,出现异常“解密错误”。 Can anyone help to find the problem?
任何人都可以帮助找到问题吗?
Android code to encrypt Android码加密
import android.util.Base64;
public static String encryptMessage(final String plainText, final PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithAndMGF1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return Base64.encodeToString(cipher.doFinal(plainText.getBytes()), Base64.NO_WRAP);
}
Pure Java code to decrypt纯Java码解密
import java.util.Base64;
public static String decryptMessage(final String encryptedText, final PrivateKey privateKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithAndMGF1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
Base64.Decoder decoder = Base64.getDecoder();
byte[] byteArray = decoder.decode(encryptedText);
byte[] decryptedArray = cipher.doFinal(byteArray); // throw exception here
String plainText = new String(decryptedArray);
return plainText;
}
You may notice I have to use different Base64 APIs in Android and pure Java.您可能会注意到我必须在 Android 和纯 Java 中使用不同的 Base64 API。 I tried "RSA/ECB/PKCS1Padding", and it can decrypt correctly without the exception.
我试过“RSA/ECB/PKCS1Padding”,它可以正确解密,无一例外。 Tried "RSA/ECB/OAEPWithSHA-256AndMGF1Padding" too but got the same exception.
也尝试了“RSA/ECB/OAEPWithSHA-256AndMGF1Padding”,但得到了同样的例外。
OAEP uses two digests, one for the OAEP label and a second as the basis for MGF1, see RFC 8017, 7.1. OAEP 使用两种摘要,一种用于 OAEP label,另一种作为 MGF1 的基础,参见 RFC 8017, 7.1。 RSAES-OAEP , B.1.
RSAES-OAEP , B.1。 Hash Functions and B.2.
Hash 功能和B.2。 Mask Generation Functions .
掩码生成函数。
The issue is caused because the providers used on both sides of the OP code (Android / API Level 28 and Java 8) apply different MGF1 digests for OAEPWithMD5AndMGF1Padding
.该问题是因为 OP 代码两侧使用的提供程序(Android / API 级别 28 和 Java 8)对
OAEPWithMD5AndMGF1Padding
应用了不同的 MGF1 摘要。
On both sides the relevant parameters (provider, OAEP digest, MGF, MGF1 digest) can be determined after the initialization of the cipher eg with:在密码初始化后,可以在两侧确定相关参数(提供者、OAEP 摘要、MGF、MGF1 摘要),例如:
OAEPParameterSpec parameterSpec = cipher.getParameters().getParameterSpec(OAEPParameterSpec.class);
System.out.println("Provider: " + cipher.getProvider().getName());
System.out.println("OAEP digest: " + parameterSpec.getDigestAlgorithm());
System.out.println("OAEP MGF : " + parameterSpec.getMGFAlgorithm());
System.out.println("OAEP MGF1 digest: " + ((MGF1ParameterSpec)parameterSpec.getMGFParameters()).getDigestAlgorithm());
With this, MD5 is determined as MGF1 digest on the Android side and SHA-1 on the Java side.这样,MD5 在 Android 侧被确定为 MGF1 摘要,在 Java 侧被确定为 SHA-1。 On both sides MD5 is used as OAEP digest.
两边都使用 MD5 作为 OAEP 摘要。 The issue can be fixed if the digests are explicitly set with
OAEPParameterSpec
so that the same digests are used on both sides.如果使用
OAEPParameterSpec
显式设置摘要以便双方使用相同的摘要,则可以解决此问题。
For example, the following code on the Java side ensures that MD5 is used as OAEP and MGF1 digest, analogous to the Android side.例如,Java 端的以下代码确保 MD5 用作 OAEP 和 MGF1 摘要,类似于 Android 端。
OAEPParameterSpec oaepParameterSpecDec = new OAEPParameterSpec("MD5", "MGF1", new MGF1ParameterSpec("MD5"), PSource.PSpecified.DEFAULT);
cipher.init(Cipher.DECRYPT_MODE, privateKey, oaepParameterSpecDec);
The same applies to OAEPWithSHA-256AndMGF1Padding
.这同样适用于
OAEPWithSHA-256AndMGF1Padding
。
Note also that RFC 8017 in B.1.另请注意B.1 中的 RFC 8017。 Hash Functions recommends SHA-1 and SHA-2 for RSAES-OAEP, but not MD5.
Hash Functions建议将 SHA-1 和 SHA-2 用于 RSAES-OAEP,但不推荐 MD5。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.