【发布时间】:2021-04-21 00:27:16
【问题描述】:
提前感谢您的阅读。
目标是从命令行加密并从 c# 解密,同时尽可能简单。我从文档开始:https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.aes?view=net-5.0
我有一个使用此 OpenSSL 命令加密的文件(无盐):
openssl enc -nosalt -aes-128-cbc -in my_file.txt -out my_file.txt.enc -p -pass pass:hello_this_is_pass
输出密钥和IV
key=2F77B7A1D3BBAA3304E53D791819958A
iv =9DD22E07DD38AF129D42E8CF3689EADD
一旦在 VS 中,这些被读入字节数组:
byte[] key = Encoding.ASCII.GetBytes("2F77B7A1D3BBAA3304E53D791819958A");
byte[] iv = Encoding.ASCII.GetBytes("9DD22E07DD38AF129D42E8CF3689EADD");
var encodedBytes = File.ReadAllBytes("myEncFile.txt.enc");
文件被读入字节数组:
这是从文档传递给阅读方法的:
static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV)
{
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Key;
aesAlg.IV = IV; // **This is the line that errors**
// Create a decryptor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
设置aesAlg.IV 会引发以下错误:
System.Security.Cryptography.CryptographicException: 'Specified initialization vector (IV) does not match the block size for this algorithm.'
看起来 aesAlg.IV 的默认值为 byte[16]。我知道这意味着我提供的 IV 是应有的两倍大,所以我认为我必须使用错误的解密器设置
Key 大小为 byte[32],我已经尝试在分配 aesAlg.IV 之前配置实例,但这些更改似乎没有效果:
aesAlg.Mode = CipherMode.CBC;
aesAlg.IVSize = 128;
aesAlg.BlockSize = 128;
aesAlg.FeedbackSize = 128;
aesAlg.Padding = PaddingMode.None;
我觉得我缺少一些非常明显的东西。此处的类似问题涉及加密,或者除非指定 -nosalt,否则 openssl 将自动添加“Salt__”这一事实。还有一个类似名称的问题“如何使用 C# 重新加密以便能够使用 OpenSSL CLI 工具进行解密?”但这并不能解决我遇到的错误(至少据我所知)。我觉得我离文档如此之近,以至于我不能成为唯一会遇到这种情况的人?
【问题讨论】:
-
我看到你在配置上没有指定填充,而不是 ISO10126。不确定这是否与您的问题有关,但它对我来说很重要,但您不应该这样做。
-
OpenSSL 将 key 和 IV 输出为十六进制编码字符串,即它们不能在 C# 代码中进行 ASCII 编码,而是进行十六进制解码,请参阅 stackoverflow.com/questions/321370/…,它将您的值映射到 16 个字节。顺便说一句:在 OpenSSL 中,key 和 IV 也可以显式指定,参见 -K、-iv 选项、openssl.org/docs/man1.1.1/man1/openssl-enc.html。如果使用密码,出于安全原因,还应使用盐。在 C# 代码中,密钥和 IV 将从密码/盐派生(而不是直接指定)。
-
谢谢@Topaco!这正是问题所在,我将字符串转换为二进制而不是十六进制字符串转换为二进制。对于任何想知道的人,这就是我转换为字节的方式:stackoverflow.com/questions/321370/…
标签: c# encryption openssl aes