[英]Decrypting AES in C# where the file was encryped using OpenSSL -nosalt; the AES is expecting a size 16 byte array IV?
thanks in advance for reading.提前感谢您的阅读。
The goal was to encrypt from command line and decrypt from c# while being as simple as possible.目标是从命令行加密并从 c# 解密,同时尽可能简单。 I'm starting from the docs: https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.aes?view=net-5.0
我从文档开始: https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.aes?view=net-5.0
I have a file encrypted with this OpenSSL command (no salt):我有一个使用此 OpenSSL 命令(无盐)加密的文件:
openssl enc -nosalt -aes-128-cbc -in my_file.txt -out my_file.txt.enc -p -pass pass:hello_this_is_pass
and that outputs the Key and IV并输出 Key 和 IV
key=2F77B7A1D3BBAA3304E53D791819958A
iv =9DD22E07DD38AF129D42E8CF3689EADD
Once in VS these were read into byte arrays with:一旦进入VS,这些被读入字节arrays:
byte[] key = Encoding.ASCII.GetBytes("2F77B7A1D3BBAA3304E53D791819958A");
byte[] iv = Encoding.ASCII.GetBytes("9DD22E07DD38AF129D42E8CF3689EADD");
var encodedBytes = File.ReadAllBytes("myEncFile.txt.enc");
The file is read into a byte array with:该文件被读入一个字节数组:
This is passed to the reading method from the docs:这从文档传递给阅读方法:
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;
}
Setting aesAlg.IV
throws the following error:设置
aesAlg.IV
会引发以下错误:
System.Security.Cryptography.CryptographicException: 'Specified initialization vector (IV) does not match the block size for this algorithm.'
It looks like the default value of aesAlg.IV is byte[16].看起来 aesAlg.IV 的默认值为 byte[16]。 I understand that this means the IV I'm providing is twice as big as it should be, so I assumed I must be using the wrong decryptor settings
我知道这意味着我提供的 IV 是应有的两倍大,所以我认为我必须使用错误的解密器设置
The Key size is byte[32], and I've tried configuring the instance prior to assigning aesAlg.IV, but these changes seemed to have no effect:密钥大小为 byte[32],我尝试在分配 aesAlg.IV 之前配置实例,但这些更改似乎没有效果:
aesAlg.Mode = CipherMode.CBC;
aesAlg.IVSize = 128;
aesAlg.BlockSize = 128;
aesAlg.FeedbackSize = 128;
aesAlg.Padding = PaddingMode.None;
I feel like there is something very obvious I'm missing.我觉得我缺少一些非常明显的东西。 The similar questions on here deal with encryption, or the fact that openssl will auto add "Salt__" unless -nosalt is specified.
此处的类似问题涉及加密,或者除非指定 -nosalt,否则 openssl 将自动添加“Salt__”这一事实。 There is also a similary named question "How I could re-encrypt in using C# so that I'd be able to decrypt with OpenSSL CLI tools?"
还有一个类似名称的问题“如何使用 C# 重新加密,以便能够使用 OpenSSL CLI 工具进行解密?” but this does not address the error I am encountering (at least as far as I can tell).
但这并不能解决我遇到的错误(至少据我所知)。 I feel like I've stuck so close to the docs that I can't be the only person who would run into this?
我觉得我离文档如此之近,以至于我不能成为唯一会遇到这种情况的人?
If anyone in the future finds this, @Topaco posted the answer in the comments.如果将来有人发现这一点,@Topaco 在评论中发布了答案。 The solution is to change
解决方法是改变
byte[] key = Encoding.ASCII.GetBytes("2F77B7A1D3BBAA3304E53D791819958A");
byte[] iv = Encoding.ASCII.GetBytes("9DD22E07DD38AF129D42E8CF3689EADD");
to至
byte[] key = StringToByteArrayFastest("2F77B7A1D3BBAA3304E53D791819958A");
byte[] iv = StringToByteArrayFastest("9DD22E07DD38AF129D42E8CF3689EADD");
Using StringToByteArrayFastest() from How can I convert a hex string to a byte array?使用如何将十六进制字符串转换为字节数组中的 StringToByteArrayFastest()?
public static byte[] StringToByteArrayFastest(string hex)
{
if (hex.Length % 2 == 1)
throw new Exception("The binary key cannot have an odd number of digits");
byte[] arr = new byte[hex.Length >> 1];
for (int i = 0; i < hex.Length >> 1; ++i)
{
arr[i] = (byte)((GetHexVal(hex[i << 1]) << 4) + (GetHexVal(hex[(i << 1) + 1])));
}
return arr;
}
public static int GetHexVal(char hex)
{
int val = (int)hex;
//For uppercase A-F letters:
//return val - (val < 58 ? 48 : 55);
//For lowercase a-f letters:
//return val - (val < 58 ? 48 : 87);
//Or the two combined, but a bit slower:
return val - (val < 58 ? 48 : (val < 97 ? 55 : 87));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.