【发布时间】:2020-05-30 07:10:39
【问题描述】:
我在 Android 中使用公钥加密了一个字符串。但是,当我尝试通过纯 Java 代码中的私钥解密加密字符串时,出现异常“解密错误”。谁能帮忙找出问题?
要加密的 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);
}
要解密的纯 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;
}
您可能注意到我必须在 Android 和纯 Java 中使用不同的 Base64 API。我试过“RSA/ECB/PKCS1Padding”,它可以正确解密,无一例外。也尝试了“RSA/ECB/OAEPWithSHA-256AndMGF1Padding”,但得到了同样的例外。
【问题讨论】:
-
有趣。首先,如果您使用错误的密文/私钥组合,也会引发填充错误,因为总是可以执行模幂运算。您能否指出您正在使用的运行时环境(Java 版本和 Android API 级别)?
-
这两个代码可能使用不同的提供程序,这些提供程序为
OAEPWithMD5AndMGF1Padding应用不同的摘要。这里必须考虑到 OAEP 在两个地方使用摘要:作为掩码生成函数 MGF1 的基础和 OAEP 标签的散列(有关详细信息,请参阅 RFC 8017)。对于解密,两个摘要必须与加密摘要相同。为了测试这一点,可以使用OAEPParameterSpec显式定义两个摘要。 -
基于 IntelliJ IDEA 2019.1.4 构建的纯 Java,Java SDK /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home。从 Android Studio 3.6.3 构建的 Android 代码; compileSdkVersion 28, buildToolsVersion '28.0.3', minSdkVersion 21, targetSdkVersion 28, androidTestImplementation 'androidx.test.ext:junit:1.1.1', androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0', 运行 AndroidTest在三星 Android 8.0.0 版中。
-
在我的机器上,BC Provider 用于 Android,API 级别 28,
OAEPWithMD5AndMGF1Padding,它将 MD5 应用于标签和 MGF。对于 Java 8,OAEPWithMD5AndMGF1Padding默认使用 SunJCE 提供程序,它对标签应用 MD5,而对 MGF 应用 SHA1。由于摘要不同,如果在两个代码中都使用OAEPWithMD5AndMGF1Padding,则无法使用Java 解密使用Android 生成的密文。这个问题可以通过OAEPParameterSpec解决。检查提供程序可能是值得的,如有必要,使用OAEPParameterSpec调整摘要。 -
@Topaco 在三星上的 Android 中,cipher.getParameters().getParameterSpec(OAEPParameterSpec.class) 抛出异常“找不到 RSA/ECB/OAEPWithAndMGF1Padding 的提供程序”。在我的 MAC 上的 Java 中,它可以工作,并为 getDigestAlgorithm() 获取 MD5,为 getMGFParameters() 获取 MGF1。
标签: java android encryption