使用OpenSSL进行AES-256/CBC加密并在C#中解密

问题描述:

我是密码学的新手。我的要求是解密/加密使用openssl加密/解密的文本。我们使用的算法是Openssl中的aes-256-cbc。 所以,我试图在我的应用程序中实现相同的功能。到目前为止,经过大量的使用Google所有我能够做的是..使用OpenSSL进行AES-256/CBC加密并在C#中解密

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 .. 。

+1

问题是什么?有问题吗?标题说“替代”?你是说你不想使用OpenSSL,而是使用其他库? – AaronLS 2013-03-18 05:22:15

+1

@AaronLS对不起,如果我不清楚..我想创建一个类来实现openssl功能....和我的问题是我的输出在这两种情况是差异...我需要解密数据加密使用以下命令打开ssl,反之亦然。 thnx – Nagaraj 2013-03-18 09:14:29

首先,阅读man enc OpenSSL的。当使用-k时,-iv被忽略。您可能需要资金-K。其次,在OpenSSL工具使用时,如果在命令行,那么你需要做的appropriate conversions而不是Encoding.ASCII.GetBytes你的C#是使用相同字符串键和IV值是十六进制(7位编码是永远正确的答案反正)。

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

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

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

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

你可以找到如何从密码派生,相同的密钥和IV为OpenSSL的从这个博客帖子Decrypting OpenSSL AES files in 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 
+0

采用openssl小写-k独自用于加密文件并对其进行解密。你能告诉我适合两者的最佳方式吗?感谢使用UTF8的建议,因为它让我对他们实际做了什么有所了解。 – Nagaraj 2013-03-18 18:20:40