AES-256 / CBC加密与OpenSSL和解密在C#(AES-256/CBC encrypti

2019-07-21 20:21发布

我在密码学是一个新手。 我的要求是解密/加密加密文本使用的OpenSSL /解密。 我们使用的算法是AES-256-CBC在OpenSSL。 所以,我想实现我的应用程序相同的功能。 到目前为止,经过大量的使用Google所有我能够做的是..

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

我的密钥长度是32digits和IV是16digits

日Thnx ...

Answer 1:

首先,阅读man enc OpenSSL的。 -iv时,忽略-k使用。 你可能需要的资本-K 。 二,关键和IV与OpenSSL的工具使用时的值是十六进制,如果在命令行,那么你需要做的C#是使用相同字符串适当的转换 ,而不是Encoding.ASCII.GetBytes (7位编码是从来没有的反正正确答案)。

为了您的纯文本,你还不如用Encoding.UTF8.GetBytes/GetString ,因为它是与ASCII向后兼容。

如果由于某种原因你真的想使用小写-k ,密码同时生成密钥和IV,这是OpenSSL的使用它自己的密钥导出方式要困难得多。 此外,它是危险与使用-nosalt标志。

-nosalt:不密钥导出程序使用的盐。 不应该被除用于测试目的或与古老的版本OpenSSL和SSLeay的兼容性使用此选项。

其中的一个原因,这是很危险的,是由于这样的事实,IV的不应该是可预见的或AES-CBC重复使用,如果你不使用盐,该密码总是会产生与打开你同样的IV相同的密钥高达数攻击和可能泄漏关于明文的信息。

你可以找到如何从密码,从这个博客帖子相同的密钥和IV为OpenSSL的派生解密OpenSSL的AES文件在C#中 ,虽然它是专门为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


文章来源: AES-256/CBC encryption with OpenSSL and decryption in C#