使用Bouncy Castle进行C# RSA解密

9

我收到了一个Base64编码的加密字符串,使用Bouncy Castle在Java中加密。以下是示例Java代码:

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, key.getPublic());
byte[] encryptedText = cipher.doFinal("xxxxx|xxxxx".getBytes("UTF-8"));
String encodedText = new BASE64Encoder().encode(encryptedText);

我需要使用Bouncy Castle在C#中解密结果字符串。我已经得到了一个Java代码片段,但我无法将其转换为C#(原因是我们正在构建一个.NET网站,并且将成为Java网站内的iFrame。 Java网站将传递RSA加密字符串到.NET网站)。以下是解密示例Java代码:

Cipher cipherDec = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipherDec.init(Cipher.DECRYPT_MODE, key.getPrivate());
byte[] decodedText = new BASE64Decoder().decodeBuffer(encodedText);
byte[] decryptedText = cipherDec.doFinal(decodedText);
String finalValue = new String(decryptedText, "UTF-8");

我已从http://www.bouncycastle.org/csharp/下载了示例,但似乎没有输入字符串值以获取加密结果并通过加密/解密过程的示例。
我已经获得了模数公共指数私人指数质数P质数q质数指数p质数指数qcrt系数的值。
我看到可以使用以下内容:
IAsymmetricBlockCipher signer = new Pkcs1Encoding(new RsaEngine());
signer.Init(true, pubParameters);

但是,signer对象似乎没有与上述Java示例相同的方法。
我唯一能使用的方法是:
ProcessBlock(byte[] inbuf, int inOff, int inLen);

但是我无法看到如何在我的情况下使用它。任何帮助将不胜感激。
3个回答

13
为了帮助他人,最终的转换代码如下:
RsaKeyParameters privParameters = new RsaPrivateCrtKeyParameters(mod, pubExp, privExp, p, q, pExp, qExp, crtCoef);
RsaKeyParameters pubParameters = new RsaKeyParameters(false, mod, pubExp);
IAsymmetricBlockCipher eng = new Pkcs1Encoding(new RsaEngine());
eng.Init(false, privParameters);
byte[] encdata = System.Convert.FromBase64String("{the enc string}");
encdata = eng.ProcessBlock(encdata, 0, encdata.Length);
string result = Encoding.UTF8.GetString(encdata);

mod、pubExp等都是BigInteger值:

static BigInteger mod = new BigInteger("big int value");

以下 using 指令是必需的:
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Encodings;
using Org.BouncyCastle.Math;

可以从bouncycastle网站获取。 http://www.bouncycastle.org/csharp/


2

谢谢Spencer,使用System.Convert.FromBase64String起作用了(我昨晚尝试过,但没有成功,所以我猜我做错了什么)。这与使用Encoding.UTF8.GetString(encdata);相结合,得到最终结果。 - mp3duck

2

我不确定为什么你必须使用Bouncycastle。以下代码片段展示了一个RSA加密/解密的例子,只使用.NET类:

using System;
using System.Text;
using System.Security.Cryptography;

namespace RsaForDotNet
{
    class Program
    {
        static void Main(string[] args)
        {
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(512);
            var encrypted_msg = rsa.Encrypt(Encoding.UTF8.GetBytes("Secret Data"), false);
            var encoded_msg = Convert.ToBase64String(encrypted_msg);
            Console.WriteLine(encoded_msg);
            var decoded_msg = Convert.FromBase64String(encoded_msg);
            var decrypted_msg = Encoding.UTF8.GetString(rsa.Decrypt(decoded_msg, false));
            Console.WriteLine(decrypted_msg);
        }
    }
}

1
谢谢。当然,我首先尝试了这个,但是他们提供给我的RSA私钥不兼容。 他们给了我BigInteger值(这是bouncycastle中的一种数据类型)。我尝试过进行一些转换(每个BigInteger对象都有一个ToByteArray()方法),但似乎无法将其转换为字符串而不带随机字符。 - mp3duck
问题是关于非对称加密的,而你的解决方案是对称加密。 - Diego
1
@Diego:我的解决方案使用非对称加密。 - President James K. Polk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接