我正在寻求帮助进行AES 256位加密,模式为CBC,IV为(16字节)00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
。
基本上我想复制this link上完成的内容。所有键都是十六进制。以下是我从其他链接中复制的内容。
以下解决方案中的几个问题:
public static String Encrypt(String plainText, String key)
{
var plainBytes = Encoding.UTF8.GetBytes(plainText);
return Convert.ToBase64String(Encrypt(plainBytes, GetRijndaelManaged(key)));
}
static RijndaelManaged GetRijndaelManaged(String secretKey)
{
var keyBytes = new byte[16];
var secretKeyBytes = Encoding.ASCII.GetBytes(secretKey);
Array.Copy(secretKeyBytes, keyBytes, Math.Min(keyBytes.Length, secretKeyBytes.Length));
return new RijndaelManaged
{
Mode = CipherMode.ECB,
Padding = PaddingMode.PKCS7,
KeySize = 128,
BlockSize = 128,
Key = keyBytes,
IV = keyBytes
};
}
static byte[] Encrypt(byte[] plainBytes, RijndaelManaged rijndaelManaged)
{
return rijndaelManaged.CreateEncryptor()
.TransformFinalBlock(plainBytes, 0, plainBytes.Length);
}
答案 0 :(得分:2)
加密和解密与链接页面兼容的两种简单方法:
public static byte[] HexToBytes(string str, string separator = " ")
{
if (str == null)
{
throw new ArgumentNullException();
}
if (separator == null)
{
separator = string.Empty;
}
if (str == string.Empty)
{
return new byte[0];
}
int stride = 2 + separator.Length;
if ((str.Length + separator.Length) % stride != 0)
{
throw new FormatException();
}
var bytes = new byte[(str.Length + separator.Length) / stride];
for (int i = 0, j = 0; i < str.Length; i += stride)
{
bytes[j] = byte.Parse(str.Substring(i, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
j++;
// There is no separator at the end!
if (j != bytes.Length && separator != string.Empty)
{
if (string.CompareOrdinal(str, i + 2, separator, 0, separator.Length) != 0)
{
throw new FormatException();
}
}
}
return bytes;
}
public static string BytesToHex(byte[] bytes, string separator = " ")
{
if (bytes == null)
{
throw new ArgumentNullException();
}
if (separator == null)
{
separator = string.Empty;
}
if (bytes.Length == 0)
{
return string.Empty;
}
var sb = new StringBuilder((bytes.Length * (2 + separator.Length)) - 1);
for (int i = 0; i < bytes.Length; i++)
{
if (i != 0)
{
sb.Append(separator);
}
sb.Append(bytes[i].ToString("x2"));
}
return sb.ToString();
}
public static byte[] SimpleEncrypt(SymmetricAlgorithm algorithm, CipherMode cipherMode, byte[] key, byte[] iv, byte[] bytes)
{
algorithm.Mode = cipherMode;
algorithm.Padding = PaddingMode.Zeros;
algorithm.Key = key;
algorithm.IV = iv;
using (var encryptor = algorithm.CreateEncryptor())
{
return encryptor.TransformFinalBlock(bytes, 0, bytes.Length);
}
}
public static byte[] SimpleDecrypt(SymmetricAlgorithm algorithm, CipherMode cipherMode, byte[] key, byte[] iv, byte[] bytes)
{
algorithm.Mode = cipherMode;
algorithm.Padding = PaddingMode.Zeros;
algorithm.Key = key;
algorithm.IV = iv;
using (var encryptor = algorithm.CreateDecryptor())
{
return encryptor.TransformFinalBlock(bytes, 0, bytes.Length);
}
}
使用它像:
string text = "xxxyyy";
string key = "da 39 a3 ee 5e 6b 4b 0d 32 55 bf ef 95 60 18 90";
string iv = "f8 01 8b 76 7c db 80 9c ed 66 fd 63 e8 41 d6 04";
var encrypted = BytesToHex(
SimpleEncrypt(
new RijndaelManaged(),
CipherMode.CBC,
HexToBytes(key),
HexToBytes(iv),
Encoding.UTF8.GetBytes(text)));
var decrypted = Encoding.UTF8.GetString(
SimpleDecrypt(
new RijndaelManaged(),
CipherMode.CBC,
HexToBytes(key),
HexToBytes(iv),
HexToBytes(encrypted))).TrimEnd('\0');
请注意,该页面不适合二进制数据,因为它使用Padding.Zeros
。问题是由这些字节组成的明文:
00 01 02 03 04 05 06 07
转换为
00 01 02 03 04 05 06 07 00 00 00 00 00 00 00 00
加密前,因为它填充为16个字符。此操作无法撤消。您使用的PaddingMode.PKCS7
更好,因为它可以颠倒,但与该页面不兼容!如果您正在加密字符串,这不是问题,因为您可以执行TrimEnd('\0')
并删除多余的\0
。您可以通过一个小的zip文件来检查它,该文件的大小不能被16整除,通过页面加密(&#34;输入类型&#34;选择文件),然后按加密,然后按下载为二进制文件。然后按“浏览”,选择刚下载的文件,按“解密”,按“下载为二进制文件”。文件大小将与原始文件不同,但您仍然可以使用zip打开它。