我正在尝试从 iOS 应用程序与 Java 后端进行通信。当使用
.rsaEncryptionOAEPSHA256
中的SecKeyCreateEncryptedData
算法进行加密时,后端显示以下堆栈跟踪:
Caused by: java.lang.SecurityException: Exception thrown while invoking doFinal(byte[]).
at ... 101 common frames omitted
Caused by: javax.crypto.BadPaddingException: Decryption error
at java.base/sun.security.rsa.RSAPadding.unpadOAEP(RSAPadding.java:497)
at java.base/sun.security.rsa.RSAPadding.unpad(RSAPadding.java:292)
at java.base/com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:366)
at java.base/com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:392)
at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2207)
... 103 common frames omitted
Java 后端使用来自
RSA/ECB/OAEPWithSHA-256AndMGF1Padding
提供商的 SunJCE
算法。该提供商使用 SHA-1
作为 MGF1 摘要。但是 iOS 的默认设置是使用 SHA-256
。
注意: 需要明确的是,完全相同的交互目前在 iOS 上使用
.rsaEncryptionPKCS1
运行良好,其中后端在 Java 中使用 RSA/ECB/PKCS1Padding
。
面临同样的问题,根据我的研究和实验,在 iOS 上支持 RSA/ECB/OAEPWithSHA-256AndMGF1Padding 实际上是不可能的。
类似问题:使用SHA-256AndMGF1Padding Swift加密RSA/ECB/OAEP
但这仅解决了算法问题,并未解决填充问题。
也许已经晚了,但我在 IOS 上尝试使用 .rsaEncryptionOAEPSHA256 在 java 中解密时遇到了同样的问题。
我通过在 cipher.init 中添加 OAEPParameterSpec 对象解决了这个问题
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode("your private key in Base64"));
KeyFactory kF = KeyFactory.getInstance("RSA")
OAEPParameterSpec miparams = new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT); //<--- create OAEPParams
PrivateKey myKey = kF.generatePrivate(keySpec);
Cipher myCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
myCipher.init(Cipher.DECRYPT_MODE, myKey,miparams); //<-- add to Cipher