AES-256/CBC encryption with OpenSSL and decryption in C#(使用 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
谢谢...
推荐答案
首先,阅读openssl的man enc
.使用 -k
时会忽略 -iv
.您可能想要大写 -K
.其次,与 openssl 工具一起使用时,key 和 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 派生 在 C# 中解密 OpenSSL AES 文件 虽然它是专门针对 AES-128 的,但注释会引导您了解如何修改 aes-256,来自 manEVP_BytesToKey
:
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# 中的解密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:使用 OpenSSL 的 AES-256/CBC 加密和 C# 中的解密
基础教程推荐
- 有没有办法忽略 2GB 文件上传的 maxRequestLength 限制? 2022-01-01
- 将 Office 安装到 Windows 容器 (servercore:ltsc2019) 失败,错误代码为 17002 2022-01-01
- 如何在 IDE 中获取 Xamarin Studio C# 输出? 2022-01-01
- rabbitmq 的 REST API 2022-01-01
- MS Visual Studio .NET 的替代品 2022-01-01
- 为什么Flurl.Http DownloadFileAsync/Http客户端GetAsync需要 2022-09-30
- SSE 浮点算术是否可重现? 2022-01-01
- c# Math.Sqrt 实现 2022-01-01
- 将 XML 转换为通用列表 2022-01-01
- 如何激活MC67中的红灯 2022-01-01