使用 RSA/ECB/OAEPWithSHA-256AndMGF1Padding 在 Java 中加密,使用 OAEPSHA256 填充在 c# 中解密
Encrypt in Java using RSA/ECB/OAEPWithSHA-256AndMGF1Padding, decrypt in c# using OAEPSHA256 Padding
我有一个 Java 程序使用 RSA/ECB/OAEPWithSHA-256AndMGF1Padding 加密文本的情况。
我需要用c#解密。
加密和解密在 Java 中工作正常。
Java 中的加密和使用 RSA/ECB/OAEPWithSHA-1AndMGF1Padding 的 c# 中的解密绝对没问题。
然而,在 Java 中使用 RSA/ECB/OAEPWithSHA-256AndMGF1Padding 加密并在 C# 中使用 OaepSHA256 解密给出了错误:参数不正确。
Java加密代码:
public static String encrypt(KeyPair keypair, String data) throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
Cipher c = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
//Cipher c = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
c.init(Cipher.ENCRYPT_MODE, keypair.getPublic());
return Base64.getEncoder().encodeToString(c.doFinal(data.getBytes()));
}
用于解密的 C# 代码:
public string DecryptRsa(byte[] encryptedBytes, X509Certificate2 x509Certificate2, RSAEncryptionPadding rSAEncryptionPadding)
{
var text = string.Empty;
using (RSACng csp = (RSACng)x509Certificate2.GetRSAPrivateKey())
{
byte[] bytesDecrypted = csp.Decrypt(encryptedBytes, rSAEncryptionPadding);
text = Encoding.UTF8.GetString(bytesDecrypted);
}
return text;
}
我做错了什么?请帮忙。
OAEP 使用两个摘要,OAEP 摘要和 MGF1 摘要,参见 RFC8017。
SunJCE 提供商使用 RSA/ECB/OAEPWithSHA-256AndMGF1Padding
将 OAEP 摘要指定为 SHA256,而 MGF1 摘要默认为 SHA1,请参阅 。另一方面,C# 代码使用 OaepSHA256
将两个摘要指定为 SHA256。因此,这两个代码是不兼容的。
解决方法是用 OAEPParameterSpec
显式指定 Java 中的摘要(出于这个原因,无论如何都应该这样做)。在 C# 方面,板载方法无法修复,因为不支持两个摘要的单独规范。但是可以使用支持这个的BouncyCastle
修复,Java 代码端(两个摘要的 SHA256):
RSAPublicKey publicKey = ...
OAEPParameterSpec oaepParameterSpec = new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT);
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPPadding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey, oaepParameterSpec);
byte[] ciphertext = cipher.doFinal(plaintext);
修复,C# 代码端,使用 BouncyCastle(SHA256 用于 OAEP 摘要,SHA1 用于 MGF1 摘要):
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Encodings;
using Org.BouncyCastle.Crypto.Parameters;
...
RsaKeyParameters privateKey = ...
OaepEncoding oaepEncoding = new OaepEncoding(new RsaEngine(), new Sha256Digest(), new Sha1Digest(), null);
oaepEncoding.Init(false, privateKey);
byte[] decrypted = oaepEncoding.ProcessBlock(ciphertext, 0, ciphertext.Length);
我有一个 Java 程序使用 RSA/ECB/OAEPWithSHA-256AndMGF1Padding 加密文本的情况。
我需要用c#解密。
加密和解密在 Java 中工作正常。
Java 中的加密和使用 RSA/ECB/OAEPWithSHA-1AndMGF1Padding 的 c# 中的解密绝对没问题。
然而,在 Java 中使用 RSA/ECB/OAEPWithSHA-256AndMGF1Padding 加密并在 C# 中使用 OaepSHA256 解密给出了错误:参数不正确。
Java加密代码:
public static String encrypt(KeyPair keypair, String data) throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
Cipher c = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
//Cipher c = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
c.init(Cipher.ENCRYPT_MODE, keypair.getPublic());
return Base64.getEncoder().encodeToString(c.doFinal(data.getBytes()));
}
用于解密的 C# 代码:
public string DecryptRsa(byte[] encryptedBytes, X509Certificate2 x509Certificate2, RSAEncryptionPadding rSAEncryptionPadding)
{
var text = string.Empty;
using (RSACng csp = (RSACng)x509Certificate2.GetRSAPrivateKey())
{
byte[] bytesDecrypted = csp.Decrypt(encryptedBytes, rSAEncryptionPadding);
text = Encoding.UTF8.GetString(bytesDecrypted);
}
return text;
}
我做错了什么?请帮忙。
OAEP 使用两个摘要,OAEP 摘要和 MGF1 摘要,参见 RFC8017。
SunJCE 提供商使用 RSA/ECB/OAEPWithSHA-256AndMGF1Padding
将 OAEP 摘要指定为 SHA256,而 MGF1 摘要默认为 SHA1,请参阅 OaepSHA256
将两个摘要指定为 SHA256。因此,这两个代码是不兼容的。
解决方法是用 OAEPParameterSpec
显式指定 Java 中的摘要(出于这个原因,无论如何都应该这样做)。在 C# 方面,板载方法无法修复,因为不支持两个摘要的单独规范。但是可以使用支持这个的BouncyCastle
修复,Java 代码端(两个摘要的 SHA256):
RSAPublicKey publicKey = ...
OAEPParameterSpec oaepParameterSpec = new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT);
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPPadding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey, oaepParameterSpec);
byte[] ciphertext = cipher.doFinal(plaintext);
修复,C# 代码端,使用 BouncyCastle(SHA256 用于 OAEP 摘要,SHA1 用于 MGF1 摘要):
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Encodings;
using Org.BouncyCastle.Crypto.Parameters;
...
RsaKeyParameters privateKey = ...
OaepEncoding oaepEncoding = new OaepEncoding(new RsaEngine(), new Sha256Digest(), new Sha1Digest(), null);
oaepEncoding.Init(false, privateKey);
byte[] decrypted = oaepEncoding.ProcessBlock(ciphertext, 0, ciphertext.Length);