使用OpenSSL进行AES-256/CBC加密,使用c#进行解密

本文关键字:使用 解密 CBC OpenSSL 进行 AES-256 加密 | 更新日期: 2023-09-27 18:04:18

我是密码学的新手。我的要求是解密/加密使用openssl加密/解密的文本。我们使用的算法是Openssl中的aes-256-cbc。所以,我试图在我的应用程序实现相同的功能。到目前为止,经过大量的谷歌搜索,我所能做的就是…

private static string Encryptor(string TextToEncrypt)
{
    //Turn the plaintext into a byte array.
    byte[] PlainTextBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(TextToEncrypt);            
    //Setup the AES providor for our purposes.
    AesCryptoServiceProvider aesProvider = new AesCryptoServiceProvider();
    aesProvider.BlockSize = 128;
    aesProvider.KeySize = 256;  
    //My key and iv that i have used in openssl
    aesProvider.Key = System.Text.Encoding.ASCII.GetBytes(strKey);
    aesProvider.IV = System.Text.Encoding.ASCII.GetBytes(strIV);  
    aesProvider.Padding = PaddingMode.PKCS7;
    aesProvider.Mode = CipherMode.CBC;
    ICryptoTransform cryptoTransform = aesProvider.CreateEncryptor(aesProvider.Key, aesProvider.IV);            
    byte[] EncryptedBytes = cryptoTransform.TransformFinalBlock(PlainTextBytes, 0, PlainTextBytes.Length);
    return Convert.ToBase64String(EncryptedBytes);                        
}
private static string Decryptor(string TextToDecrypt)
{
    byte[] EncryptedBytes = Convert.FromBase64String(TextToDecrypt);
    //Setup the AES provider for decrypting.            
    AesCryptoServiceProvider aesProvider = new AesCryptoServiceProvider();
    //aesProvider.Key = System.Text.Encoding.ASCII.GetBytes(strKey);
    //aesProvider.IV = System.Text.Encoding.ASCII.GetBytes(strIV);
    aesProvider.BlockSize = 128;
    aesProvider.KeySize = 256;  
    //My key and iv that i have used in openssl
    aesProvider.Key = System.Text.Encoding.ASCII.GetBytes(strKey);
    aesProvider.IV = System.Text.Encoding.ASCII.GetBytes(strIV);  
    aesProvider.Padding = PaddingMode.PKCS7;
    aesProvider.Mode = CipherMode.CBC;

    ICryptoTransform cryptoTransform = aesProvider.CreateDecryptor(aesProvider.Key, aesProvider.IV);
    byte[] DecryptedBytes = cryptoTransform.TransformFinalBlock(EncryptedBytes, 0, EncryptedBytes.Length);
    return System.Text.Encoding.ASCII.GetString(DecryptedBytes);
}
我的openssl命令是
openssl aes-256-cbc -e -nosalt -a -in  inputfile.txt -out  output.txt -k key -iv ivkey

我的密钥长度是32位,iv是16位

感谢…

使用OpenSSL进行AES-256/CBC加密,使用c#进行解密

首先,读取openssl的man enc。使用-k时,忽略-iv。你可能需要大写的-K。其次,当与openssl工具一起使用时,key和iv值是十六进制的,如果您的c#使用与命令行相同的字符串,那么您需要进行适当的转换,而不是Encoding.ASCII.GetBytes(无论如何,7位编码永远不会是正确的答案)。

对于纯文本,您不妨使用Encoding.UTF8.GetBytes/GetString,因为它与ASCII向后兼容。

如果出于某种原因,你想使用小写的-k,一个同时生成密钥和iv的密码,这要困难得多,因为openssl使用它自己的密钥派生方案。此外,与-nosalt标志一起使用也很危险。

-nosalt :在密钥派生例程中不使用salt。这个选项应该不得使用,除非用于测试目的或与古代的兼容性OpenSSL和SSLeay的版本

这是危险的原因之一,是由于IV不应该被预测或重用为AES-CBC,如果你不使用盐,密码短语将始终产生相同的密钥与相同的IV打开你的几个攻击,并可以泄漏有关明文的信息。

你可以从这篇博客文章中找到如何从passphrase,与openssl相同的密钥和IV中导出,在c#中解密openssl AES文件,尽管它专门针对AES-128,但注释引导你如何修改AES- 256,从man EVP_BytesToKey:

Hash0 = ''
Hash1 = MD5(Hash0 + Password + Salt)
Hash2 = MD5(Hash1 + Password + Salt)
Hash3 = MD5(Hash2 + Password + Salt)
Key = Hash1 + Hash2
IV = Hash3