4

我是密码学的新手。我的要求是解密/加密使用 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

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

谢谢...

4

1 回答 1

1

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

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

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

-nosalt:在密钥派生例程中不使用盐。除非出于测试目的或与 OpenSSL 和 SSLeay 的旧版本兼容,否则不应使用此选项。

这是危险的原因之一,因为 IV 不应该被预测或重复用于 AES-CBC,如果您不使用盐,密码将始终生成具有相同 IV 的相同密钥来打开您最多可以进行多次攻击,并且可以泄露有关明文的信息。

您可以从这篇博文Decrypting OpenSSL AES files in C#中了解如何从密码短语、与 openssl 相同的密钥和 IV 派生,尽管它是专门针对 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
于 2013-03-18T13:44:08.200 回答