AES 解密无法识别的 unicode 结果
Unrecognized unicode result from AES decryption
我尝试为 encrypt/decrypt 一些字符串构建简单的 AES 加密助手
拳头,我有一个填充模式的问题,其中只有在零时才接受解密,否则会发生有关填充的错误!
第二个问题是当我尝试加密简单字符串时 "Hello World," 它被加密了,我有 base64 字符串,但是当尝试解密时,没有错误,但是显示了一个奇怪的未知字符!像㡲啁䎰廾ử靱㡲啁廰廾ử靱
我的代码:
private static int keySizes = 256;
private static int blockSize = 128;
private static PaddingMode pMode = PaddingMode.Zeros;
private static CipherMode cMode = CipherMode.ECB;
private static byte[] key = GenEncryptionKey();
private const string passphrase = @"StartYourMorningWithASmile";
private static byte[] GenEncryptionKey()
{
HashAlgorithm hash = MD5.Create();
return hash.ComputeHash(Encoding.Unicode.GetBytes(passphrase));
}
private static AesManaged CreateCryptor()
{
AesManaged cryptor = new AesManaged();
cryptor.KeySize = keySizes;
cryptor.BlockSize = blockSize;
cryptor.Padding = pMode;
cryptor.Key = key;
cryptor.Mode = cMode;
cryptor.GenerateIV();
return cryptor;
}
public static string EncryptParams(string reqVal)
{
string cipherText = "";
if (string.IsNullOrEmpty(reqVal) || reqVal.Length < 1)
throw new ArgumentNullException();
byte[] plainBytes = Encoding.Unicode.GetBytes(reqVal);
using (var cryptor = CreateCryptor())
{
ICryptoTransform encryptor = cryptor.CreateEncryptor();
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
cs.Write(plainBytes, 0, plainBytes.Length);
}
byte[] cipherBytes = ms.ToArray();
cipherText = Convert.ToBase64String(cipherBytes);
}
cryptor.Clear();
}
return cipherText;
}
public static string DecryptParams(string resVal)
{
var data = Convert.FromBase64String(resVal);
byte[] cipherBytes = new byte[data.Length];
string plainText = "";
using (var crypto = CreateCryptor())
{
ICryptoTransform Dec = crypto.CreateDecryptor();
using (MemoryStream ms = new MemoryStream())
{
using (var cs = new CryptoStream(ms, Dec, CryptoStreamMode.Write))
{
cs.Write(cipherBytes, 0, cipherBytes.Length);
plainText = Encoding.Unicode.GetString(ms.ToArray());
}
}
crypto.Clear();
}
return plainText;
}
更新 1:
正如@maarten-bodewes 指出的那样,请自行设置 IV 以实现成功解密。我错过了那部分,解密以某种方式(?)与您现有的代码一起工作,但您始终应该为对称加密算法提供相同的密钥和 IV,以使其双向工作。
原始答案:
您的解密失败(产生不正确的结果),因为您错误地实现了解密部分(通过使用 CryptoStreamMode.Write
而不是 CryptoStreamMode.Read
)并且除了向解密流提供全零字节之外
在
的执行点
cs.Write(cipherBytes, 0, cipherBytes.Length);
变量cipherBytes
全为零。真正的加密缓冲区在 data
变量中,你只用它来设置 cipherBytes
的长度
所以把你的解密方式改成这样
BONUS:修正解密部分后,您可以根据需要指定填充!我用PKCS7测试没问题
public static string DecryptParams(string resVal)
{
var cipherBytes = Convert.FromBase64String(resVal);
string plainText = "";
using (var crypto = CreateCryptor())
{
ICryptoTransform Dec = crypto.CreateDecryptor();
using (MemoryStream ms = new MemoryStream(cipherBytes))
{
using (var cs = new CryptoStream(ms, Dec, CryptoStreamMode.Read))
{
byte[] decryptBlock = new byte[4096];
MemoryStream decryptStream = new MemoryStream();
int readBytes;
while ((readBytes = cs.Read(decryptBlock, 0, 4096)) > 0)
{
decryptStream.Write(decryptBlock, 0, readBytes);
}
plainText = Encoding.Unicode.GetString(decryptStream.ToArray());
}
}
crypto.Clear();
}
return plainText;
}
希望对您有所帮助。
感谢奥古兹
以下是我修改后的描述方法
public static string DecryptParams(string resVal)
{
var data = Convert.FromBase64String(resVal);
byte[] cipherBytes = new byte[data.Length];
string plainText = "";
using (var crypto = CreateCryptor())
{
ICryptoTransform Dec = crypto.CreateDecryptor();
using (MemoryStream ms = new MemoryStream(data))
{
using (var cs = new CryptoStream(ms, Dec, CryptoStreamMode.Read))
{
cs.Read(cipherBytes, 0, cipherBytes.Length);
plainText = Encoding.Unicode.GetString(cipherBytes.ToArray());
}
}
crypto.Clear();
}
return plainText;
}
关于解密后 return 结果的另一件事我得到了原始字符串加上 [=17=][=17=][=17=][=17=] 所以我使用 myString.TrimEnd('\0') 来解决这个问题。
我尝试为 encrypt/decrypt 一些字符串构建简单的 AES 加密助手 拳头,我有一个填充模式的问题,其中只有在零时才接受解密,否则会发生有关填充的错误! 第二个问题是当我尝试加密简单字符串时 "Hello World," 它被加密了,我有 base64 字符串,但是当尝试解密时,没有错误,但是显示了一个奇怪的未知字符!像㡲啁䎰廾ử靱㡲啁廰廾ử靱 我的代码:
private static int keySizes = 256;
private static int blockSize = 128;
private static PaddingMode pMode = PaddingMode.Zeros;
private static CipherMode cMode = CipherMode.ECB;
private static byte[] key = GenEncryptionKey();
private const string passphrase = @"StartYourMorningWithASmile";
private static byte[] GenEncryptionKey()
{
HashAlgorithm hash = MD5.Create();
return hash.ComputeHash(Encoding.Unicode.GetBytes(passphrase));
}
private static AesManaged CreateCryptor()
{
AesManaged cryptor = new AesManaged();
cryptor.KeySize = keySizes;
cryptor.BlockSize = blockSize;
cryptor.Padding = pMode;
cryptor.Key = key;
cryptor.Mode = cMode;
cryptor.GenerateIV();
return cryptor;
}
public static string EncryptParams(string reqVal)
{
string cipherText = "";
if (string.IsNullOrEmpty(reqVal) || reqVal.Length < 1)
throw new ArgumentNullException();
byte[] plainBytes = Encoding.Unicode.GetBytes(reqVal);
using (var cryptor = CreateCryptor())
{
ICryptoTransform encryptor = cryptor.CreateEncryptor();
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
cs.Write(plainBytes, 0, plainBytes.Length);
}
byte[] cipherBytes = ms.ToArray();
cipherText = Convert.ToBase64String(cipherBytes);
}
cryptor.Clear();
}
return cipherText;
}
public static string DecryptParams(string resVal)
{
var data = Convert.FromBase64String(resVal);
byte[] cipherBytes = new byte[data.Length];
string plainText = "";
using (var crypto = CreateCryptor())
{
ICryptoTransform Dec = crypto.CreateDecryptor();
using (MemoryStream ms = new MemoryStream())
{
using (var cs = new CryptoStream(ms, Dec, CryptoStreamMode.Write))
{
cs.Write(cipherBytes, 0, cipherBytes.Length);
plainText = Encoding.Unicode.GetString(ms.ToArray());
}
}
crypto.Clear();
}
return plainText;
}
更新 1:
正如@maarten-bodewes 指出的那样,请自行设置 IV 以实现成功解密。我错过了那部分,解密以某种方式(?)与您现有的代码一起工作,但您始终应该为对称加密算法提供相同的密钥和 IV,以使其双向工作。
原始答案:
您的解密失败(产生不正确的结果),因为您错误地实现了解密部分(通过使用 CryptoStreamMode.Write
而不是 CryptoStreamMode.Read
)并且除了向解密流提供全零字节之外
在
的执行点cs.Write(cipherBytes, 0, cipherBytes.Length);
变量cipherBytes
全为零。真正的加密缓冲区在 data
变量中,你只用它来设置 cipherBytes
所以把你的解密方式改成这样
BONUS:修正解密部分后,您可以根据需要指定填充!我用PKCS7测试没问题
public static string DecryptParams(string resVal)
{
var cipherBytes = Convert.FromBase64String(resVal);
string plainText = "";
using (var crypto = CreateCryptor())
{
ICryptoTransform Dec = crypto.CreateDecryptor();
using (MemoryStream ms = new MemoryStream(cipherBytes))
{
using (var cs = new CryptoStream(ms, Dec, CryptoStreamMode.Read))
{
byte[] decryptBlock = new byte[4096];
MemoryStream decryptStream = new MemoryStream();
int readBytes;
while ((readBytes = cs.Read(decryptBlock, 0, 4096)) > 0)
{
decryptStream.Write(decryptBlock, 0, readBytes);
}
plainText = Encoding.Unicode.GetString(decryptStream.ToArray());
}
}
crypto.Clear();
}
return plainText;
}
希望对您有所帮助。
感谢奥古兹
以下是我修改后的描述方法
public static string DecryptParams(string resVal)
{
var data = Convert.FromBase64String(resVal);
byte[] cipherBytes = new byte[data.Length];
string plainText = "";
using (var crypto = CreateCryptor())
{
ICryptoTransform Dec = crypto.CreateDecryptor();
using (MemoryStream ms = new MemoryStream(data))
{
using (var cs = new CryptoStream(ms, Dec, CryptoStreamMode.Read))
{
cs.Read(cipherBytes, 0, cipherBytes.Length);
plainText = Encoding.Unicode.GetString(cipherBytes.ToArray());
}
}
crypto.Clear();
}
return plainText;
}
关于解密后 return 结果的另一件事我得到了原始字符串加上 [=17=][=17=][=17=][=17=] 所以我使用 myString.TrimEnd('\0') 来解决这个问题。