RSA/ECB/PKCS1Padding 使用模数和指数在 C# 中解密
RSA/ECB/PKCS1Padding Decryption in C# using Modulus and Exponent
我有一个来自 java 服务器的加密值。我需要解密它。该服务的文档为我提供了以下解密算法,提供商将向我发送 "m" 和 "e" 值:
Java代码:
private String RSA_Decryption(String encryptedData)
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IOException, IllegalBlockSizeException, BadPaddingException, GeneralSecurityException
{
BigInteger m = new BigInteger("verylongnumber1");
BigInteger e = new BigInteger("verylongnumber2");
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(m, e);
KeyFactory fact = KeyFactory.getInstance("RSA");
PrivateKey privateKey = fact.generatePrivate(keySpec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
byte[] decValue = cipher.doFinal(decordedValue);
String decryptedValue = new String(decValue, "UTF-8");
return decryptedValue;
}
我需要在 C# 中转换它。到目前为止,我尝试了以下 C# 代码(使用 .NET 中的 BigInteger class):
string m = "verylongnumber1";
string e = "verylongnumber2";
RSAParameters info = new RSAParameters();
var modulus = BigInteger.Parse(m).ToByteArray();
if (modulus.Length == 129) Array.Resize(ref modulus, 128); // it gives me 129 characters, the last being 0
var exponent = BigInteger.Parse(e).ToByteArray();
info.Modulus = modulus.Reverse().ToArray();
info.D = exponent.Reverse().ToArray();
var encryptedData = Convert.FromBase64String(@"gEQwzXpaARzC2pz9ahiyji8G/K9xecMzh6qi7hMmih4kR4hBwwjfcX83lNet91/hzHX9if1XwAe7/fO5xgXR8qLY+sZu9mj+iXiaSgYyQO3VyxcMD6q/wiVBXpOCX/LmG6qCVbFgn6LZvvcx9fUjVEn3FJFpqUhQh9PvNjmg8ks=");
var decryptedValue = this.Decrypt(encryptedData, info);
string decryptedBarcode = Encoding.Default.GetString(decryptedValue);
byte[] decryptedBytes;
using (RSACryptoServiceProvider rsa1 = new RSACryptoServiceProvider())
{
rsa1.ImportParameters(info); // throws exception with "Bad data" message
decryptedBytes = rsa1.Decrypt(encryptedData, false);
}
但是,当我想在 rsa1 实例中导入 keyInfo 时,我得到了 "Bad Data" 消息的异常。
我也试过:
- 设置info.Exponent而不是info.D
- 使用 Chew Keong 提供的 BigInteger class 和 getBytes 方法获取模数和指数的字节(另外,在 info.Exponent 和 info.D 中设置数组,有和没有反向).
一切都导致与 "Bad Data" 消息相同的异常。
任何人都可以帮我翻译这个 java 等效的 C# 代码吗?
不幸的是,标准的 RSACryptoServiceProvider 不适合这种特定情况......自己看看:
如果您尝试导入 RSAParameters,有几个字段需要您填写...
模数...您的密钥对的公共模数...在您的情况下为 m
指数 ... public 指数 ... public 密钥的一部分,用于加密
D ... 私有指数 ... 私钥的一部分,用于解密,在您的例子中为 e
P 和 Q ... 密钥对的 2 个素数 ... P*Q=模数
DP 和 DQ ... 数学快捷方式(中国余数定理)的中间值,用于更快的解密方式
所以……你得到了模数和私有指数……虽然这通常足以解密,但它不是完整的密钥对……缺少 P 和 Q……P 和Q 我们可以计算剩下的...
如果你想解密,RSACryptoServiceProvider 希望你提供完整的密钥对......一个缺失的值,你会得到那个讨厌的 cryptographicexception 告诉你 "bad data"
soo ... 一切都丢失了?不......前段时间还有另一个关于 RSA 的问题,为此我写了几行只使用 bigintegers 来处理 RSA,根本没有 RSACryptoServiceProvider ... Public key encryption with RSACryptoServiceProvider
也许这可以帮助您解密您的价值
我有一个来自 java 服务器的加密值。我需要解密它。该服务的文档为我提供了以下解密算法,提供商将向我发送 "m" 和 "e" 值:
Java代码:
private String RSA_Decryption(String encryptedData)
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IOException, IllegalBlockSizeException, BadPaddingException, GeneralSecurityException
{
BigInteger m = new BigInteger("verylongnumber1");
BigInteger e = new BigInteger("verylongnumber2");
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(m, e);
KeyFactory fact = KeyFactory.getInstance("RSA");
PrivateKey privateKey = fact.generatePrivate(keySpec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
byte[] decValue = cipher.doFinal(decordedValue);
String decryptedValue = new String(decValue, "UTF-8");
return decryptedValue;
}
我需要在 C# 中转换它。到目前为止,我尝试了以下 C# 代码(使用 .NET 中的 BigInteger class):
string m = "verylongnumber1";
string e = "verylongnumber2";
RSAParameters info = new RSAParameters();
var modulus = BigInteger.Parse(m).ToByteArray();
if (modulus.Length == 129) Array.Resize(ref modulus, 128); // it gives me 129 characters, the last being 0
var exponent = BigInteger.Parse(e).ToByteArray();
info.Modulus = modulus.Reverse().ToArray();
info.D = exponent.Reverse().ToArray();
var encryptedData = Convert.FromBase64String(@"gEQwzXpaARzC2pz9ahiyji8G/K9xecMzh6qi7hMmih4kR4hBwwjfcX83lNet91/hzHX9if1XwAe7/fO5xgXR8qLY+sZu9mj+iXiaSgYyQO3VyxcMD6q/wiVBXpOCX/LmG6qCVbFgn6LZvvcx9fUjVEn3FJFpqUhQh9PvNjmg8ks=");
var decryptedValue = this.Decrypt(encryptedData, info);
string decryptedBarcode = Encoding.Default.GetString(decryptedValue);
byte[] decryptedBytes;
using (RSACryptoServiceProvider rsa1 = new RSACryptoServiceProvider())
{
rsa1.ImportParameters(info); // throws exception with "Bad data" message
decryptedBytes = rsa1.Decrypt(encryptedData, false);
}
但是,当我想在 rsa1 实例中导入 keyInfo 时,我得到了 "Bad Data" 消息的异常。
我也试过:
- 设置info.Exponent而不是info.D
- 使用 Chew Keong 提供的 BigInteger class 和 getBytes 方法获取模数和指数的字节(另外,在 info.Exponent 和 info.D 中设置数组,有和没有反向).
一切都导致与 "Bad Data" 消息相同的异常。
任何人都可以帮我翻译这个 java 等效的 C# 代码吗?
不幸的是,标准的 RSACryptoServiceProvider 不适合这种特定情况......自己看看:
如果您尝试导入 RSAParameters,有几个字段需要您填写...
模数...您的密钥对的公共模数...在您的情况下为 m
指数 ... public 指数 ... public 密钥的一部分,用于加密
D ... 私有指数 ... 私钥的一部分,用于解密,在您的例子中为 e
P 和 Q ... 密钥对的 2 个素数 ... P*Q=模数
DP 和 DQ ... 数学快捷方式(中国余数定理)的中间值,用于更快的解密方式
所以……你得到了模数和私有指数……虽然这通常足以解密,但它不是完整的密钥对……缺少 P 和 Q……P 和Q 我们可以计算剩下的...
如果你想解密,RSACryptoServiceProvider 希望你提供完整的密钥对......一个缺失的值,你会得到那个讨厌的 cryptographicexception 告诉你 "bad data"
soo ... 一切都丢失了?不......前段时间还有另一个关于 RSA 的问题,为此我写了几行只使用 bigintegers 来处理 RSA,根本没有 RSACryptoServiceProvider ... Public key encryption with RSACryptoServiceProvider
也许这可以帮助您解密您的价值