java - 使用模数和指数在 C# 中进行 RSA/ECB/PKCS1Padding 解密

标签 java c# .net cryptography rsa

我有一个来自 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类):

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 时,出现“错误数据”消息的异常。

我也尝试过:

  • 设置 info.Exponent 而不是 info.D
  • 使用 Chew Keong 提供的 BigInteger 类和 getBytes 方法来获取模数和指数的字节(同时,在 info.Exponent 和 info.D 中设置带有或不带有反向的数组)。

一切都会导致相同的异常,并显示“错误数据”消息。

任何人都可以帮我将此 Java 代码翻译成 C# 等效代码吗?

最佳答案

不幸的是,标准 RSACryptoServiceProvider 不适合这种特定情况......请亲自查看:

如果您尝试导入 RSAParameters,有几个字段需要您填写...

模数...您的 key 对的常用模数...在您的情况下
指数...公共(public)指数...公钥的一部分,用于加密

D ... 私有(private)指数 ... 私钥的一部分,用于解密,在您的情况下为 e

P 和 Q ... key 对的 2 个质数 ...P*Q=Modulus
DP 和 DQ ...数学捷径(中国剩余定理)的中间值,用于更快的解密方式

所以...你得到了模数和私有(private)指数...虽然这通常足以解密,但它不是完整的 key 对...P和Q丢失了...有了P和Q我们可以计算其余的...

如果您想解密...一个缺失值,RSACryptoServiceProvider 希望您提供完整的 key 对,您将收到令人讨厌的加密异常,告诉您“错误数据”

soo ...一切都失去了?不...前段时间有另一个关于 RSA 的问题,我为此写了几行,仅使用大整数来处理 RSA,根本没有 RSACryptoServiceProvider ... Public key encryption with RSACryptoServiceProvider

也许这可以帮助您解密您的值

关于java - 使用模数和指数在 C# 中进行 RSA/ECB/PKCS1Padding 解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27835498/

相关文章:

java - 如何在java中调整缓存密集型应用程序?

java - 单选按钮无法正确显示

c# - 如何从命令行使用 msbuild 编译我的 C# 解决方案

c# - 基于 .NET 服务器的 PDF 生成

java - JVM 如何处理标记接口(interface)

java - 如何处理 Java 8/JSR 310/threeten.org 中 ISO-8601 时间戳中的 'optional' T?

c# - 如何在运行时在 .net 中向对象添加属性?

c# - 如何使用 EmguCV (OpenCV) 绘制具有抗锯齿和高斯线强度的圆?

c# - 在对象成为孤立对象之前,我是否需要从对象中删除事件订阅?

c# - SQL:使用带有 LIMIT 的 INNER JOIN 进行更新