RSA解密错误

时间:2017-05-31 13:57:21

标签: c# cryptography rsa

我试图用RSA的小字符串加密和解密文件。 加密字符串后,程序会写入文件私钥和加密文本。

要加密的代码:

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(4096);
string pub = rsa.ToXmlString(false);
string priv = rsa.ToXmlString(true);
string to_crypt = "Hello world, try to crypt me";

byte[] dataToEncrypt = Encoding.ASCII.GetBytes(to_crypt);
rsa.FromXmlString(pub);
dataToEncrypt = rsa.Encrypt(dataToEncrypt, false);

string s = System.Text.Encoding.UTF8.GetString(dataToEncrypt, 0, dataToEncrypt.Length);
WriteFile("crypt", priv+s);

另一个程序读取数组中的文本并尝试解密:

using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(4096))
{
byte[] to_decrypt = File.ReadAllBytes(args[0]);
byte[] key = new byte[3219];
byte[] text = new byte[to_decrypt.Length - key.Length];
Buffer.BlockCopy(to_decrypt, 0, key, 0, key.Length);
Buffer.BlockCopy(to_decrypt, key.Length, text, 0, text.Length);

string skey = System.Text.Encoding.UTF8.GetString(key, 0, key.Length);
rsa.FromXmlString(skey);
rsa.Decrypt(text, false);        <---- Error: Bad data
    ...

我有错误:

  

CryptographicException:错误的数据

我在文本数组中犯了错误?数组的大小错误?

2 个答案:

答案 0 :(得分:0)

RSA加密到密文,密文不是UTF-8,而是没有任何字符编码的字节数组。

如果您想通过文本界面传输它,那么您应该在加密后使用64编码,并在解密之前使用base64解码。

您当然也可以使用加密内容创建二进制文件。

这在加密期间:

string s = System.Text.Encoding.UTF8.GetString(dataToEncrypt, 0, dataToEncrypt.Length);

这在解密期间:

byte[] key = new byte[3219];
byte[] text = new byte[to_decrypt.Length - key.Length];
Buffer.BlockCopy(to_decrypt, 0, key, 0, key.Length);
Buffer.BlockCopy(to_decrypt, key.Length, text, 0, text.Length);
...
string skey = System.Text.Encoding.UTF8.GetString(key, 0, key.Length);

是你不想要也不需要的东西。

答案 1 :(得分:0)

最简单的错误:你在文件的末尾写了一个换行符,并且正在读取换行符to_decrypt / text,使其大于两个(在Windows上)大于实际的密文。比较dataToEncrypt(已加密时)和text的长度。

正如Maarten已经说过的,我们中的许多人已经说过无数次,(真实/现代)密码学中没有字符串,只有字节。当需要时,Base64是一种在文本流上发送字节的稳定方式。您的另一个错误来源可能是您在“密文”的文本解释中得到\0(这不是文本,而是来自基于字符的加密的遗留名称)并且它不是圆形跳闸你希望或期望的方式。我不认为这是你当前的问题,因为你把数据分离作为字节处理。

而且,正如一个FYI:基于XML的密钥导出/导入在.NET Core中不起作用,您应该使用基于RSAParameters的{​​{1}} / ImportParameters代替。