如何在没有IV的情况下使用AES 128进行加密和解密?

6

我目前需要一种使用AES-128对称加密算法,在C#中加密字符串并解密字节数组的方法。我找不到如何实现这一点,但也许我错过了什么。


2
为什么你想要避免使用IVs?它们是一个重要的安全特性。 - CodesInChaos
1
进一步解释@CodesInChaos的评论。IV可以随机生成并与密文一起明文传输。IV的保密性对于安全性并非必要。IV的要求是不重复使用相同的密钥和IV组合,并且IV难以预测。 - Dev
这个问题是关于一个项目,有人对使用AES进行加密而不使用IV感兴趣。尽管如此,我同意IV是一个重要的安全特性! - kdh
1个回答

13

导入命名空间

using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;

     static void Main(string[] args)
        {
            string value = "@arifansari300<3>";

            string encryptedValue= EncryptDecrypt.Encrypt(value);

            string decryptedValue = EncryptDecrypt.Decrypt(encryptedValue);
        }

    public static string Encrypt(string clearText)
    {
        string EncryptionKey = "MAKV2SPBNI99212";
        byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
        using (Aes encryptor = Aes.Create())
        {
            Rfc2898DeriveBytes pdb = new 
                Rfc2898DeriveBytes(EncryptionKey, new byte[] 
                { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
            encryptor.Key = pdb.GetBytes(32);
            encryptor.IV = pdb.GetBytes(16);
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(clearBytes, 0, clearBytes.Length);
                    cs.Close();
                }
                clearText = Convert.ToBase64String(ms.ToArray());
            }
        }
        return clearText;
    }

    public static string Decrypt(string cipherText)
    {
        string EncryptionKey = "MAKV2SPBNI99212";
        byte[] cipherBytes = Convert.FromBase64String(cipherText);
        using (Aes encryptor = Aes.Create())
        {
            Rfc2898DeriveBytes pdb = new 
                Rfc2898DeriveBytes(EncryptionKey, new byte[] 
                { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
            encryptor.Key = pdb.GetBytes(32);
            encryptor.IV = pdb.GetBytes(16);
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(cipherBytes, 0, cipherBytes.Length);
                    cs.Close();
                }
                cipherText = Encoding.Unicode.GetString(ms.ToArray());
            }
        }
        return cipherText;
    }

2
当您必须使用最终用户输入的密码而不是生成适当的密钥时,“Rfc2898DeriveBytes”才是一个好选择。但在这种情况下,您应该使用盐(在您的示例中它是一个常量,这忽略了IV的重点)和更多迭代(至少20k,最好更多)。如果您有一个适当的密钥,则普通加密更简单且快得多 - CodesInChaos
我该如何将这个函数转换为PHP? - user3581428
5
请确保更改盐值为:0x49、0x76、0x61、0x6e、0x20、0x4d、0x65、0x64、0x76、0x65、0x64、0x65、0x76 = Ivan Medvedev - Mathias
这段代码如此古老,它可能来自于这里(https://social.msdn.microsoft.com/Forums/vstudio/en-US/245037b3-9c92-4bbd-bab0-6852002c26aa/decrypt-hash?forum=clr),该链接缩略自这里(https://web.archive.org/web/20080208125623/http://www.dotnetthis.com/Articles/Crypto.htm)。在2019年,每个人仍然都想念“Ivan Medvedev”的那个。 - Bagus Tesa
非常好的贡献。 - Maurico Flores
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接