简体   繁体   English

不同的加密 Android 与纯 Java - RSA/ECB/OAEPWithMD5AndMGF1Padding

[英]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-OAEPB.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.

相关问题 Java 7:使用密码“ RSA / ECB / OAEPWithSHA1AndMGF1Padding”使用公共RSA密钥加密的输出与openssl命令不匹配 - Java 7 : output from encryption with public RSA key using cipher “RSA/ECB/OAEPWithSHA1AndMGF1Padding” does not match with openssl command Java RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING 迁移到 Go - Java RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING Migrate To Go java RSA/ECB/OAEPWithSHA 256AndMGF1Padding 在 golang 中等效 - java RSA/ECB/OAEPWithSHA 256AndMGF1Padding equivalent in golang 使用RSA / ECB / PKCS1padding的Android加密问题。 它在Java和Android中给出不同的结果 - Issue in Android Encryption using RSA/ECB/PKCS1padding. It gives different results in Java and Android Java的RSA / ECB / OAEPWITHSHA-256ANDMGF1PADDING在PHP中等效 - Java's RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING equivalent in PHP Java 的 RSA/ECB/OAEPWithSHA-256AndMGF1Padding 在 Node.js 中的等价物 - Java's RSA/ECB/OAEPWithSHA-256AndMGF1Padding equivalent in Node.js C#等效于Java RSA / ECB / OAEPWithSHA-256AndMGF1Padding - C# equivalent to Java RSA/ECB/OAEPWithSHA-256AndMGF1Padding “RSA/ECB/OAEPWITHSHA256ANDMGF1PADDING”和“RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING”之间的区别是什么 - what is deference between "RSA/ECB/OAEPWITHSHA256ANDMGF1PADDING" and "RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING" 分解 RSA/ECB/OAEPWithSHA-256AndMGF1Padding - Breaking down RSA/ECB/OAEPWithSHA-256AndMGF1Padding 获取 ruby 的“RSA/ECB/OAEPWithSHA-256AndMGF1Padding”组合 - Get this “RSA/ECB/OAEPWithSHA-256AndMGF1Padding” combination for ruby
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM