带有OpenSSL的AES-256 / CBC加密和C#中的解密 [英] AES-256/CBC encryption with OpenSSL and decryption in C#

查看:307
本文介绍了带有OpenSSL的AES-256 / CBC加密和C#中的解密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am a newbie to cryptography. My requirement is to decrypt/encrypt the text that is encrypted/decrypted using openssl. The algorithm that we are using is aes-256-cbc in the Openssl. So, I am trying to implement the same functionality in my application. so far after a lot of googling all i was able to do is..

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命令是

My openssl command is

openssl aes-256-cbc -e -nosalt -a -in  inputfile.txt -out  output.txt -k key -iv ivkey

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

My key length is 32digits and iv is 16digits

Thnx ...

推荐答案

首先,阅读 man enc 了解openssl。使用 -k 时,将忽略 -iv 。您可能需要大写 -K 。其次,与openssl工具一起使用时,键和iv值为十六进制,如果您的C#使用与命令行相同的字符串,则您需要执行适当的转换而不是 Encoding.ASCII.GetBytes (7位编码永远是不正确的答案)。

First, read man enc for openssl. -iv is ignored when -k is used. You probably want capital -K. Second, the key and iv values are hexadecimal when used with the openssl tool, if your C# is using the same string as the command line then you need to do appropriate conversions rather than Encoding.ASCII.GetBytes (a 7 bit encoding is never the right answer anyway).

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

For your plain text, you might as well use Encoding.UTF8.GetBytes/GetString since it is backwards compatible with ASCII.

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

If for some reason you actually want to use lowercase -k, a password to generate both the key and iv, that is much more difficult as openssl uses it's own key derivation scheme. Also, it is dangerous to use with the -nosalt flag.


-nosalt
在密钥派生例程中不使用盐。除了测试目的或与古代
版本的OpenSSL和SSLeay兼容之外,不应使用此选项

-nosalt: doesn't use a salt in the key derivation routines. This option SHOULD NOT be used except for test purposes or compatibility with ancient versions of OpenSSL and SSLeay.

之所以很危险,原因之一是IV不可预测或不能再用于AES-CBC,如果您不使用盐,密码短语将始终使用打开的相同IV产生相同的密钥您最多可以遭受几次攻击,并且可能泄漏有关纯文本的信息。

One of the reasons this is dangerous, is due to the fact that IV's should not be predictable or reused for AES-CBC and if you don't use a salt, the passphrase will always produce the same key with the same IV that opens you up to several attacks and can leak info about the plaintext.

您可以在此博客文章中找到如何从密码短语,与openssl相同的密钥和IV派生< a href = http://deusty.blogspot.com/2009/04/decrypting-openssl-aes-files-in-c.html rel = nofollow noreferrer>在C#中解密OpenSSL AES文件尽管它是专门针对AES-128的注释,它引导您如何从 man EVP_BytesToKey 中修改aes-256:

You can find out how to derive from passphrase, the same key and IV as openssl from this blog post Decrypting OpenSSL AES files in C# although it is specifically for AES-128 the comments lead you to how to modify for aes-256, from man EVP_BytesToKey:

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

Key = Hash1 + Hash2
IV = Hash3

这篇关于带有OpenSSL的AES-256 / CBC加密和C#中的解密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆