Mik*_*J82 2 .net c# aes cbc-mode .net-core
我正在搜索 C# 代码来重现以下 openssl 命令。
openssl enc -d -aes-256-cbc -in my_encrypted_file.csv.enc -out my_decrypted_file.csv -pass file:key.bin
附加信息:
我一直在尝试通过搜索网络找到的各种示例。问题是,所有这些例子都需要 IV(初始化向量)。不幸的是,我没有 IV,团队中没有人知道这是什么或如何定义它。openssl 命令似乎不需要一个,所以我对此有点困惑。
目前,我正在尝试使用的代码如下所示:
public static string DecryptAesCbc(byte[] cipheredData, byte[] key)
{
string decrypted;
System.Security.Cryptography.Aes aes = System.Security.Cryptography.Aes.Create();
aes.KeySize = 256;
aes.Key = key;
byte[] iv = new byte[aes.BlockSize / 8];
aes.IV = iv;
aes.Mode = CipherMode.CBC;
ICryptoTransform decipher = aes.CreateDecryptor(aes.Key, aes.IV);
using (MemoryStream ms = new MemoryStream(cipheredData))
{
using (CryptoStream cs = new CryptoStream(ms, decipher, CryptoStreamMode.Read))
{
using (StreamReader sr = new StreamReader(cs))
{
decrypted = sr.ReadToEnd();
}
}
return decrypted;
}
}
Run Code Online (Sandbox Code Playgroud)
该代码失败,表明我的 byte[256] 密钥对于此类算法的长度错误。
感谢您对此的任何帮助!
干杯,迈克
发布的 OpenSSL 语句使用该-pass file:选项以及密码(从文件中读取),请参阅openssl enc。这导致加密过程首先生成随机的8 字节盐,然后与密码一起使用(不是很安全)专有的 OpenSSL 函数导出 32 字节密钥和 16 字节 IV EVP_BytesToKey。该函数使用多个参数,例如摘要和迭代计数。密钥派生的默认摘要为MD5,迭代计数为 1。请注意,OpenSSL 版本1.1.0及更高版本使用SHA256作为默认摘要,即根据用于生成密文的 OpenSSL 版本,必须使用适当的摘要进行解密。密文之前是一个块,其前 8 个字节是 的 ASCII 编码Salted__,后面是 8 个字节的盐。
因此,解密首先要确定盐。基于盐,必须与密码一起导出密钥和 IV,然后才能解密其余的加密数据。因此,首先EVP_BytesToKey需要在 C# 中实现,例如here。那么一个可能的实现可以是(使用MD5作为摘要):
public static string DecryptAesCbc(byte[] cipheredData, string passphrase)
{
string decrypted = null;
using (MemoryStream ms = new MemoryStream(cipheredData))
{
// Get salt
byte[] salt = new byte[8];
ms.Seek(8, SeekOrigin.Begin);
ms.Read(salt, 0, 8);
// Derive key and IV
OpenSslCompat.OpenSslCompatDeriveBytes db = new OpenSslCompat.OpenSslCompatDeriveBytes(passphrase, salt, "MD5", 1);
byte[] key = db.GetBytes(32);
byte[] iv = db.GetBytes(16);
using (Aes aes = Aes.Create())
{
aes.Padding = PaddingMode.PKCS7;
aes.Mode = CipherMode.CBC;
aes.Key = key;
aes.IV = iv;
// Decrypt
ICryptoTransform decipher = aes.CreateDecryptor(aes.Key, aes.IV);
using (CryptoStream cs = new CryptoStream(ms, decipher, CryptoStreamMode.Read))
{
using (StreamReader sr = new StreamReader(cs, Encoding.UTF8))
{
decrypted = sr.ReadToEnd();
}
}
}
}
return decrypted;
}
Run Code Online (Sandbox Code Playgroud)
请注意, 的第二个参数DecryptAesCbc是密码(as string)而不是密钥(as byte[])。另请注意,StreamReader使用编码(默认为 UTF-8),这需要兼容的数据(即文本数据,但这对于csv文件应该满足)。否则(即对于二进制数据而不是文本数据)StreamReader不得使用。
| 归档时间: |
|
| 查看次数: |
8750 次 |
| 最近记录: |