gpt4 book ai didi

c# - Rijndael 填充错误

转载 作者:太空狗 更新时间:2023-10-30 00:27:50 25 4
gpt4 key购买 nike

您好,我正在尝试通过 Rijaendal 加密/解密字符串。我根本无法弄清楚为什么解密会失败。我总是以不正确的填充错误结束。让我失望的一件事是我作为 HEX 数组返回的加密结果。它的长度为 14 个字节。在我的解密函数中,相同的字节数组在从 HEX 转换后最终有 16 个字节。

任何帮助将不胜感激:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace rjandal
{
class Program
{
static void Main(string[] args)
{
string DataForEncrypting = "this is a test";

string key = string.Empty;
string iv = string.Empty;

using (System.Security.Cryptography.RijndaelManaged rmt = new System.Security.Cryptography.RijndaelManaged())
{
rmt.KeySize = 256;
rmt.BlockSize = 128;
rmt.Mode = System.Security.Cryptography.CipherMode.CBC;
rmt.Padding = System.Security.Cryptography.PaddingMode.ISO10126;
rmt.GenerateKey();
rmt.GenerateIV();
key = Convert.ToBase64String(rmt.Key);
iv = Convert.ToBase64String(rmt.IV);
}

string encryptedData = _encrypt(DataForEncrypting, key, iv);
string unencryptedData = _decrypt(key, iv, HexString2Ascii(encryptedData));

Console.WriteLine(unencryptedData);
Console.WriteLine(encryptedData);
Console.ReadKey();
}

private static string _encrypt(string value, string key, string initVector)
{
byte[] buffer = ASCIIEncoding.ASCII.GetBytes(value);
byte[] encBuffer;
using (System.Security.Cryptography.RijndaelManaged rmt = new System.Security.Cryptography.RijndaelManaged())
{
rmt.KeySize = 256;
rmt.BlockSize = 128;
rmt.Mode = System.Security.Cryptography.CipherMode.CBC;
rmt.Padding = System.Security.Cryptography.PaddingMode.ISO10126;
encBuffer = rmt.CreateEncryptor(Convert.FromBase64String(key),
Convert.FromBase64String(initVector)).TransformFinalBlock(buffer, 0, buffer.Length);
}
string encryptValue = ConvertToHex(ASCIIEncoding.ASCII.GetString(encBuffer));
return encryptValue;
}

private static string _decrypt(string key, string initVector, string value)
{
byte[] hexBuffer = ASCIIEncoding.ASCII.GetBytes(value);
byte[] decBuffer;
using (System.Security.Cryptography.RijndaelManaged rmt = new System.Security.Cryptography.RijndaelManaged())
{
rmt.KeySize = 256;
rmt.BlockSize = 128;
rmt.Mode = System.Security.Cryptography.CipherMode.CBC;
rmt.Padding = System.Security.Cryptography.PaddingMode.ISO10126;
decBuffer = rmt.CreateDecryptor(Convert.FromBase64String(key),
Convert.FromBase64String(initVector)).TransformFinalBlock(hexBuffer, 0, hexBuffer.Length);
}

return System.Text.ASCIIEncoding.ASCII.GetString(decBuffer);
}

private static string ConvertToHex(string asciiString)
{
string hex = "";
foreach (char c in asciiString)
{
int tmp = c;
hex += String.Format("{0:x2}", (uint)System.Convert.ToUInt32(tmp.ToString()));
}
return hex;
}

private static string HexString2Ascii(string hexString)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i <= hexString.Length - 2; i += 2)
{
sb.Append(Convert.ToString(Convert.ToChar(Int32.Parse(hexString.Substring(i, 2), System.Globalization.NumberStyles.HexNumber))));
}
return sb.ToString();
}

}
}

最佳答案

基本上,您在文本和数据之间进行了太多转换。看看这个,例如:

string encryptValue = ConvertToHex(ASCIIEncoding.ASCII.GetString(encBuffer));

一旦获得 ASCII 字符串,为什么还需要将 那个 转换成十六进制?已经是文字了!但到那时你已经丢失了数据。除非你真的需要它是十六进制的(在这种情况下遵循 Adam 的建议并更改你的 HexToAscii 方法以采用字节 [] 而不是字符串)你应该只使用 Convert.ToBase64String:

string encryptValue = Convert.ToBase64String(encBuffer);

解密时在另一端使用Convert.FromBase64String。然后您可以完全摆脱您的十六进制方法。

哦,一般来说,我不会使用 Encoding.ASCII 开始......我几乎总是使用 Encoding.UTF8 来代替。目前,您将无法(正确地)加密任何包含非 ASCII 字符(例如重音符号)的字符串。

这是您的测试程序的重新调整版本,其中进行了一些更改。请注意,名称“密文”和“纯文本”是在加密方面......它们仍然是二进制数据而不是文本!

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

class Program
{
static void Main(string[] args)
{
string DataForEncrypting = "this is a test";

string key = string.Empty;
string iv = string.Empty;

using (RijndaelManaged rmt = new RijndaelManaged())
{
rmt.KeySize = 256;
rmt.BlockSize = 128;
rmt.Mode = CipherMode.CBC;
rmt.Padding = PaddingMode.ISO10126;
rmt.GenerateKey();
rmt.GenerateIV();
key = Convert.ToBase64String(rmt.Key);
iv = Convert.ToBase64String(rmt.IV);
}

string encryptedData = _encrypt(DataForEncrypting, key, iv);
string unencryptedData = _decrypt(key, iv, encryptedData);

Console.WriteLine(unencryptedData);
Console.WriteLine(encryptedData);
Console.ReadKey();
}

private static string _encrypt(string value, string key, string initVector)
{
using (RijndaelManaged rmt = new RijndaelManaged())
{
rmt.KeySize = 256;
rmt.BlockSize = 128;
rmt.Mode = CipherMode.CBC;
rmt.Padding = PaddingMode.ISO10126;
byte[] plainText = Encoding.UTF8.GetBytes(value);
byte[] cipherText = rmt.CreateEncryptor(Convert.FromBase64String(key),
Convert.FromBase64String(initVector))
.TransformFinalBlock(plainText, 0, plainText.Length);
return Convert.ToBase64String(cipherText);
}
}

private static string _decrypt(string key, string initVector, string value)
{
using (RijndaelManaged rmt = new RijndaelManaged())
{
rmt.KeySize = 256;
rmt.BlockSize = 128;
rmt.Mode = CipherMode.CBC;
rmt.Padding = PaddingMode.ISO10126;
byte[] cipherText = Convert.FromBase64String(value);
byte[] plainText = rmt.CreateDecryptor(Convert.FromBase64String(key),
Convert.FromBase64String(initVector))
.TransformFinalBlock(cipherText, 0, cipherText.Length);
return Encoding.UTF8.GetString(plainText);
}
}
}

关于c# - Rijndael 填充错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4925798/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com