C# 这个密码安全吗?

C# 这个密码安全吗?,c#,security,encryption,aes,rijndaelmanaged,C#,Security,Encryption,Aes,Rijndaelmanaged,使用此代码的应用程序必须足够安全,以在机密级别加密机密数据 我知道rijndaelManaged类未经FIPS批准,但这不会影响安全性,因此我认为只要文件使用相同的应用程序加密和解密,就可以使用该类 对于机密信息,此加密代码是否足够安全 public static class AESEncryption { private static readonly byte[] initVectorBytes = Encoding.ASCII.GetBytes("tu89geji340t89u2"

使用此代码的应用程序必须足够安全,以在机密级别加密机密数据

我知道rijndaelManaged类未经FIPS批准,但这不会影响安全性,因此我认为只要文件使用相同的应用程序加密和解密,就可以使用该类

对于机密信息,此加密代码是否足够安全

public static class AESEncryption
{
    private static readonly byte[] initVectorBytes = Encoding.ASCII.GetBytes("tu89geji340t89u2");
    private const int keysize = 256;
    public static string Encrypt(string plainText, string passPhrase)
    {
        byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
        using (PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null))
        {
            byte[] keyBytes = password.GetBytes(keysize / 8);
            using (RijndaelManaged symmetricKey = new RijndaelManaged())
            {
                symmetricKey.Mode = CipherMode.CBC;
                using (ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes))
                {
                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                        {
                            cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
                            cryptoStream.FlushFinalBlock();
                            byte[] cipherTextBytes = memoryStream.ToArray();
                            return Convert.ToBase64String(cipherTextBytes);
                        }
                    }
                }
            }
        }
    }

    public static string Decrypt(string cipherText, string passPhrase)
    {
        byte[] cipherTextBytes = Convert.FromBase64String(cipherText);
        using (PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null))
        {
            byte[] keyBytes = password.GetBytes(keysize / 8);
            using (RijndaelManaged symmetricKey = new RijndaelManaged())
            {
                symmetricKey.Mode = CipherMode.CBC;
                using (ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes))
                {
                    using (MemoryStream memoryStream = new MemoryStream(cipherTextBytes))
                    {
                        using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                        {
                            byte[] plainTextBytes = new byte[cipherTextBytes.Length];
                            int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
                            return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
                        }
                    }
                }
            }
        }
    }
}

您没有使用经过身份验证的加密。这允许攻击修改消息,尽管他无法读取消息

您使用的是常数IV。这是一种信息泄漏,因为攻击者可以判断您是否多次加密同一消息

IV的目的不是硬编码为某个特定值。让crypto API为您生成一个

您容易受到攻击,因为您正在泄漏检测到无效填充的信息

除了这些问题之外,这段代码实际上看起来相当不错


我建议您使用适用于.NET的AES-GCM。它是对数据进行加密和身份验证的集成原语。很难出错。

您没有使用经过身份验证的加密。这允许攻击修改消息,尽管他无法读取消息

您使用的是常数IV。这是一种信息泄漏,因为攻击者可以判断您是否多次加密同一消息

IV的目的不是硬编码为某个特定值。让crypto API为您生成一个

您容易受到攻击,因为您正在泄漏检测到无效填充的信息

除了这些问题之外,这段代码实际上看起来相当不错


我建议您使用适用于.NET的AES-GCM。它是对数据进行加密和身份验证的集成原语。很难出错。

现在已经不是了。From:“对于CBC和CFB,重复使用IV会泄露一些关于第一块明文以及两条消息共享的任何公共前缀的信息。”。CBC,检查。修复(并因此重复使用)IV,检查。@nsgocev它怎么不再安全了?IV应该是公开的,对吗?1)没有经过身份验证的加密/MAC 2)KDF中没有盐3)固定IV没有抓住IV的要点。你永远不应该重用(IV,密钥)对。如果您使用salt,这不会是一个问题,因为这样键就可以一次性使用。4)
encryptor.TransformFinalBlock
产生了更简单的代码,因为您不需要那些无用的流。现在不再需要了。From:“对于CBC和CFB,重用IV会泄漏一些关于第一块明文的信息,以及关于两条消息共享的任何公共前缀的信息。”。CBC,检查。修复(并因此重复使用)IV,检查。@nsgocev它怎么不再安全了?IV应该是公开的,对吗?1)没有经过身份验证的加密/MAC 2)KDF中没有盐3)固定IV没有抓住IV的要点。你永远不应该重用(IV,密钥)对。如果您使用salt,这不会是一个问题,因为这样键就可以一次性使用。4)
encryptor.TransformFinalBlock
会产生更简单的代码,因为你不需要那些无用的流。你能解释一下填充oracle攻击以及如何避免它吗?我不需要iv来解密数据,你需要用加密数据存储iv。通常它是预先准备好的。静脉注射不是秘密。@usr我不是有意要求生成随机静脉注射。我不理解你的问题,因为你逐字写了“我如何生成随机静脉注射?”。无论如何,希望你的问题得到回答。你能解释一下填充oracle攻击以及如何避免它吗?我不需要iv来解密数据,你需要用加密数据存储iv。通常它是预先准备好的。静脉注射不是秘密。@usr我不是有意要求生成随机静脉注射。我不理解你的问题,因为你逐字写了“我如何生成随机静脉注射?”。不管怎样,希望你的问题得到回答。