当我用AES加密和解密字节[128]{1,2,…,126,127}时,一切正常:
// Create Key & iv
byte[] key = GenerateKey();
byte[] iv = GenerateIV();
// Create raw byte array 0-127
byte[] raw = new byte[128];
for (byte i = 0; i < 128; i++)
{
raw[i] = i;
}
// Encrypt
var encrypted = Encrypt(raw, key, iv);
// Decrypt
var decrypted = Decrypt(encrypted, key, iv);
解密后将输出字节[128]{1,2,…,126,127}。但当我将raw改为字节[127]{128,129,…,253,254}为相同的加密/解密逻辑时,结果变成字节[381],在[2391189]的循环中:
// Create Key & iv
byte[] key = GenerateKey();
byte[] iv = GenerateIV();
// Create raw byte array 128-254
byte[] raw = new byte[127];
for (byte i = 128; i <= 254; i++)
{
raw[i-128] = i;
}
// Encrypt
var encrypted = Encrypt(raw, key, iv);
// Decrypt
var decrypted = Decrypt(encrypted, key, iv);
现在解密后将输出字节[381]{239,191,189,…,239,191,189}
一开始我认为超过127是不同的,直到我发现以下字节数组也可以工作:
// Create Key & iv
byte[] key = GenerateKey();
byte[] iv = GenerateIV();
// Create raw byte array from Poruguese ÇÃ
string rawPortuguese = "ÇÃ";
byte[] raw = Encoding.UTF8.GetBytes(rawPortuguese);
现在原始是byte[4]{195, 135, 195, 131},每个数字都大于127。
// Encrypt
var encrypted = Encrypt(raw, key, iv);
// Decrypt
var decrypted = Decrypt(encrypted, key, iv);
但也能正确解密,解密的是字节[4]{195,135,195,131}现在我完全搞糊涂了,为什么原始数据字节[127]{128,129,…,253,254}不能正确解密?
密钥/IV/加密/解密代码:
static byte[] GenerateKey()
{
using (AesCng cng = new AesCng())
{
cng.GenerateKey();
return cng.Key;
}
}
static byte[] GenerateIV()
{
using (AesCng cng = new AesCng())
{
cng.GenerateIV();
return cng.IV;
}
}
static byte[] Encrypt(byte[] raw, byte[] key, byte[] iv, CipherMode mode = CipherMode.CBC, PaddingMode padding = PaddingMode.PKCS7)
{
byte[] encrypted;
using (AesCng cng = new AesCng())
{
cng.Mode = mode;
cng.Padding = padding;
cng.Key = key;
cng.IV = iv;
using (ICryptoTransform encryptor = cng.CreateEncryptor())
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
csEncrypt.Write(raw, 0, raw.Length);
}
encrypted = msEncrypt.ToArray();
}
}
return encrypted;
}
static byte[] Decrypt(byte[] encrypted, byte[] key, byte[] iv, CipherMode mode = CipherMode.CBC, PaddingMode padding = PaddingMode.PKCS7)
{
byte[] decryptedData;
string plaintext = null;
byte[] plainData = null;
using (AesCng cng = new AesCng())
{
cng.Mode = mode;
cng.Padding = padding;
cng.Key = key;
decryptedData = encrypted;
cng.IV = iv;
using (ICryptoTransform decryptor = cng.CreateDecryptor())
{
using (MemoryStream msDecrypt = new MemoryStream(decryptedData))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
plaintext = srDecrypt.ReadToEnd();
}
plainData = Encoding.UTF8.GetBytes(plaintext);
}
}
}
}
return plainData;
}
这就是问题所在:
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
plaintext = srDecrypt.ReadToEnd();
}
plainData = Encoding.UTF8.GetBytes(plaintext);
您将纯文本数据视为UTF-8,将其转换为字符串,然后将其转换回字节(再次使用UTF-8)。如果纯文本数据真的是UTF-8编码的文本(就像您的葡萄牙语示例中那样),那么这很好,但对于任意字节数组,情况并非如此。字节序列0x80、0x81、0x82、0x83。。。0xff不是有效的UTF-8。
除非你知道数据是有效文本,否则你不应该将其视为文本——这总是会导致这样的问题。在这种情况下,“纯文本”这个名称并不真正意味着文本——这是一个不幸的术语。它只是意味着“未加密的数据”。
如果您只想有效地读取任意流并从中创建数组,请使用另一个内存流,将数据复制到该流,然后使用内存流。ToArray要将其转换为字节[],请执行以下操作:
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (var plainData = new MemoryStream())
{
csDescrypt.CopyTo(plainData);
return plainData.ToArray();
}
}
我正在从https://docs.AWS.amazon.com/cli/latest/reference/kms/encrypt.html和https://docs.AWS.amazon.com/cli/latest/reference/kms/decrypt.html读取AWS加密cli文档。我发现我可以在不创建数据密钥的情况下加密/解密。当我阅读https://docs.aws.amazon.
我使用密码加密和解密字节数组在Android发送到服务器。我没有使用字符串,但我仍然收到非法块大小异常。 2021-08-12 20:55:17.606 15222-15222/com.example.packageW/System.err:javax.crypto.IllegalBlockSizeExcture:错误:1e00006a:密码函数:OPENSSL_internal:DATA_NOT
问题内容: 我正在使用以下LINK 进行加密,并使用Strings进行了尝试,并且可以正常工作。但是,由于我要处理图像,因此我需要对字节数组进行加密/解密过程。因此,我将该链接中的代码修改为以下内容: 而检查器类是: 但是我的输出是: 因此,解密后的文本与纯文本不同。知道我在原始链接中尝试了该示例并且该示例可与Strings一起使用时,该怎么办才能解决此问题? 问题答案: 您所看到的是数组的toS
为什么数学模块返回错误的结果? 结果 在这里,结果是正确的。 结果 这里的结果是不正确的。 为什么会这样呢?
问题内容: 我究竟做错了什么?我希望Java程序打印“专用”。我的目标是尝试用Java编写MessageEncryptor.decrypt ruby方法。 Ruby加密(大多数代码来自MessageEncryptor,但未修改为Marshal),但我已将其提取出来,以便更轻松地了解正在发生的情况: 哪个打印: tzFUIVllG2FcYD7xqGPmHQ ==-UAPvdm3oN3Hog9ND
问题内容: 我有以下加密数据: 对其进行解密的密码是: (这是来自胡言乱语的例子) 在命令行中使用openssl: 输出为: 使用我的NodeJS应用程序: 我在一行中遇到以下错误。 我想念什么吗?谢谢。 问题答案: 加密的数据以8字节的“魔术”开头,表示存在盐(的ASCII编码)。然后接下来的8个字节是盐。现在是个坏消息:Node.js似乎没有对EVP_BytesToKey方法使用盐: 那是盐。