C# 这个Rijndael在生产系统中使用是否足够安全?

C# 这个Rijndael在生产系统中使用是否足够安全?,c#,encryption,production-environment,rijndael,C#,Encryption,Production Environment,Rijndael,找到了如何在上实现Rijndael的示例 此代码对于生产系统是否足够安全 using System; using System.IO; using System.Text; using System.Security.Cryptography; 此类使用对称密钥算法(Rijndael/AES)来加密和 解密数据。只要加密和解密例程使用相同的 参数生成密钥,保证密钥相同。 该类使用带有重复代码的静态函数,以便于 演示加密和解密逻辑。在实际应用中, 这可能不是处理加密的最有效方法,因此 一旦你对

找到了如何在上实现Rijndael的示例

此代码对于生产系统是否足够安全

using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;
此类使用对称密钥算法(Rijndael/AES)来加密和 解密数据。只要加密和解密例程使用相同的 参数生成密钥,保证密钥相同。 该类使用带有重复代码的静态函数,以便于 演示加密和解密逻辑。在实际应用中, 这可能不是处理加密的最有效方法,因此 一旦你对它感到满意,你可能会想重新设计这个类。

公共类RijndaelSimple
{
/// 
///使用Rijndael对称密钥算法加密指定的明文
///并返回base64编码的结果。
/// 
/// 
///要加密的明文值。
/// 
/// 
///从中派生伪随机密码的密码短语
///派生密码将用于生成加密密钥。
///密码短语可以是任何字符串
///密码短语是ASCII字符串。
/// 
/// 
///Salt值与密码短语一起用于生成密码。Salt可以
///可以是任意字符串。在本例中,我们假设salt是ASCII字符串。
/// 
/// 
///用于生成密码的哈希算法。允许的值为:“MD5”和
///SHA1散列稍微慢一点,但比MD5散列更安全。
/// 
/// 
///用于生成密码的迭代次数。一次或两次迭代
///应该足够了。
/// 
/// 
///初始化向量(或IV)。加密
///第一块纯文本数据。对于RijndaelManaged class IV,必须
///正好16个ASCII字符长。
/// 
/// 
///加密密钥的大小(位)。允许的值为:128、192和256。
///长密钥比短密钥更安全。
/// 
/// 
///格式为base64编码字符串的加密值。
/// 
公共静态字符串加密(字符串明文,
字符串密码短语,
字符串saltValue,
字符串哈希算法,
整数密码迭代,
字符串初始化向量,
int键(大小)
{
//将字符串转换为字节数组。
//让我们假设字符串只包含ASCII码。
//如果字符串包含Unicode字符,请使用Unicode、UTF7或UTF8
//编码。
byte[]initVectorBytes=Encoding.ASCII.GetBytes(initVector);
byte[]saltValueBytes=Encoding.ASCII.GetBytes(saltValue);
//将明文转换为字节数组。
//让我们假设纯文本包含UTF8编码字符。
字节[]明文字节=Encoding.UTF8.GetBytes(明文);
//首先,我们必须创建一个密码,从中派生密钥。
//此密码将根据指定的密码短语生成,并且
//salt值。将使用指定的哈希创建密码
//密码创建可以在多次迭代中完成。
PasswordDeriveBytes password=新的PasswordDeriveBytes(
密码短语,
saltValueBytes,
哈希算法,
密码迭代);
//使用密码为加密生成伪随机字节
//密钥。以字节(而不是位)为单位指定密钥的大小。
byte[]keyBytes=password.GetBytes(keySize/8);
//创建未初始化的Rijndael加密对象。
RijndaelManaged symmetricKey=新的RijndaelManaged();
//将加密模式设置为密码块链接是合理的
//(CBC)。对其他对称密钥参数使用默认选项。
symmetricKey.Mode=CipherMode.CBC;
//从现有密钥字节和初始化生成加密程序
//密钥大小将根据密钥的数量定义
//字节。
ICryptoTransform encryptor=symmetricKey.CreateEncryptor(
密钥字节,
initVectorBytes);
//定义用于保存加密数据的内存流。
MemoryStream MemoryStream=新的MemoryStream();
//定义加密流(始终使用写入模式进行加密)。
CryptoStream CryptoStream=新加密流(memoryStream,
加密机,
CryptoStreamMode.Write);
//开始加密。
cryptoStream.Write(明文字节,0,明文字节.Length);
//完成加密。
cryptoStream.FlushFinalBlock();
//将加密数据从内存流转换为字节数组。
byte[]cipherTextBytes=memoryStream.ToArray();
//关闭两条溪流。
memoryStream.Close();
cryptoStream.Close();
//将加密数据转换为base64编码字符串。
字符串密文=Convert.ToBase64String(密文字节);
//返回加密字符串。
返回密文;
}
/// 
///使用Rijndael对称密钥算法解密指定的密文。
/// 
/// 
///Base64格式的密文值。
/// 
/// 
///从中派生伪随机密码的密码短语
///派生密码将用于生成加密密钥。
///密码短语c
public class RijndaelSimple
{
    /// <summary>
    /// Encrypts specified plaintext using Rijndael symmetric key algorithm
    /// and returns a base64-encoded result.
    /// </summary>
    /// <param name="plainText">
    /// Plaintext value to be encrypted.
    /// </param>
    /// <param name="passPhrase">
    /// Passphrase from which a pseudo-random password will be derived. The
    /// derived password will be used to generate the encryption key.
    /// Passphrase can be any string. In this example we assume that this
    /// passphrase is an ASCII string.
    /// </param>
    /// <param name="saltValue">
    /// Salt value used along with passphrase to generate password. Salt can
    /// be any string. In this example we assume that salt is an ASCII string.
    /// </param>
    /// <param name="hashAlgorithm">
    /// Hash algorithm used to generate password. Allowed values are: "MD5" and
    /// "SHA1". SHA1 hashes are a bit slower, but more secure than MD5 hashes.
    /// </param>
    /// <param name="passwordIterations">
    /// Number of iterations used to generate password. One or two iterations
    /// should be enough.
    /// </param>
    /// <param name="initVector">
    /// Initialization vector (or IV). This value is required to encrypt the
    /// first block of plaintext data. For RijndaelManaged class IV must be 
    /// exactly 16 ASCII characters long.
    /// </param>
    /// <param name="keySize">
    /// Size of encryption key in bits. Allowed values are: 128, 192, and 256. 
    /// Longer keys are more secure than shorter keys.
    /// </param>
    /// <returns>
    /// Encrypted value formatted as a base64-encoded string.
    /// </returns>
    public static string Encrypt(string   plainText,
                                 string   passPhrase,
                                 string   saltValue,
                                 string   hashAlgorithm,
                                 int      passwordIterations,
                                 string   initVector,
                                 int      keySize)
    {
        // Convert strings into byte arrays.
        // Let us assume that strings only contain ASCII codes.
        // If strings include Unicode characters, use Unicode, UTF7, or UTF8 
        // encoding.
        byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
        byte[] saltValueBytes  = Encoding.ASCII.GetBytes(saltValue);

        // Convert our plaintext into a byte array.
        // Let us assume that plaintext contains UTF8-encoded characters.
        byte[] plainTextBytes  = Encoding.UTF8.GetBytes(plainText);

        // First, we must create a password, from which the key will be derived.
        // This password will be generated from the specified passphrase and 
        // salt value. The password will be created using the specified hash 
        // algorithm. Password creation can be done in several iterations.
        PasswordDeriveBytes password = new PasswordDeriveBytes(
                                                        passPhrase, 
                                                        saltValueBytes, 
                                                        hashAlgorithm, 
                                                        passwordIterations);

        // Use the password to generate pseudo-random bytes for the encryption
        // key. Specify the size of the key in bytes (instead of bits).
        byte[] keyBytes = password.GetBytes(keySize / 8);

        // Create uninitialized Rijndael encryption object.
        RijndaelManaged symmetricKey = new RijndaelManaged();

        // It is reasonable to set encryption mode to Cipher Block Chaining
        // (CBC). Use default options for other symmetric key parameters.
        symmetricKey.Mode = CipherMode.CBC;        

        // Generate encryptor from the existing key bytes and initialization 
        // vector. Key size will be defined based on the number of the key 
        // bytes.
        ICryptoTransform encryptor = symmetricKey.CreateEncryptor(
                                                         keyBytes, 
                                                         initVectorBytes);

        // Define memory stream which will be used to hold encrypted data.
        MemoryStream memoryStream = new MemoryStream();        

        // Define cryptographic stream (always use Write mode for encryption).
        CryptoStream cryptoStream = new CryptoStream(memoryStream, 
                                                     encryptor,
                                                     CryptoStreamMode.Write);
        // Start encrypting.
        cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);

        // Finish encrypting.
        cryptoStream.FlushFinalBlock();

        // Convert our encrypted data from a memory stream into a byte array.
        byte[] cipherTextBytes = memoryStream.ToArray();

        // Close both streams.
        memoryStream.Close();
        cryptoStream.Close();

        // Convert encrypted data into a base64-encoded string.
        string cipherText = Convert.ToBase64String(cipherTextBytes);

        // Return encrypted string.
        return cipherText;
    }

    /// <summary>
    /// Decrypts specified ciphertext using Rijndael symmetric key algorithm.
    /// </summary>
    /// <param name="cipherText">
    /// Base64-formatted ciphertext value.
    /// </param>
    /// <param name="passPhrase">
    /// Passphrase from which a pseudo-random password will be derived. The
    /// derived password will be used to generate the encryption key.
    /// Passphrase can be any string. In this example we assume that this
    /// passphrase is an ASCII string.
    /// </param>
    /// <param name="saltValue">
    /// Salt value used along with passphrase to generate password. Salt can
    /// be any string. In this example we assume that salt is an ASCII string.
    /// </param>
    /// <param name="hashAlgorithm">
    /// Hash algorithm used to generate password. Allowed values are: "MD5" and
    /// "SHA1". SHA1 hashes are a bit slower, but more secure than MD5 hashes.
    /// </param>
    /// <param name="passwordIterations">
    /// Number of iterations used to generate password. One or two iterations
    /// should be enough.
    /// </param>
    /// <param name="initVector">
    /// Initialization vector (or IV). This value is required to encrypt the
    /// first block of plaintext data. For RijndaelManaged class IV must be
    /// exactly 16 ASCII characters long.
    /// </param>
    /// <param name="keySize">
    /// Size of encryption key in bits. Allowed values are: 128, 192, and 256.
    /// Longer keys are more secure than shorter keys.
    /// </param>
    /// <returns>
    /// Decrypted string value.
    /// </returns>
    /// <remarks>
    /// Most of the logic in this function is similar to the Encrypt
    /// logic. In order for decryption to work, all parameters of this function
    /// - except cipherText value - must match the corresponding parameters of
    /// the Encrypt function which was called to generate the
    /// ciphertext.
    /// </remarks>
    public static string Decrypt(string   cipherText,
                                 string   passPhrase,
                                 string   saltValue,
                                 string   hashAlgorithm,
                                 int      passwordIterations,
                                 string   initVector,
                                 int      keySize)
    {
        // Convert strings defining encryption key characteristics into byte
        // arrays. Let us assume that strings only contain ASCII codes.
        // If strings include Unicode characters, use Unicode, UTF7, or UTF8
        // encoding.
        byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
        byte[] saltValueBytes  = Encoding.ASCII.GetBytes(saltValue);

        // Convert our ciphertext into a byte array.
        byte[] cipherTextBytes = Convert.FromBase64String(cipherText);

        // First, we must create a password, from which the key will be 
        // derived. This password will be generated from the specified 
        // passphrase and salt value. The password will be created using
        // the specified hash algorithm. Password creation can be done in
        // several iterations.
        PasswordDeriveBytes password = new PasswordDeriveBytes(
                                                        passPhrase, 
                                                        saltValueBytes, 
                                                        hashAlgorithm, 
                                                        passwordIterations);

        // Use the password to generate pseudo-random bytes for the encryption
        // key. Specify the size of the key in bytes (instead of bits).
        byte[] keyBytes = password.GetBytes(keySize / 8);

        // Create uninitialized Rijndael encryption object.
        RijndaelManaged    symmetricKey = new RijndaelManaged();

        // It is reasonable to set encryption mode to Cipher Block Chaining
        // (CBC). Use default options for other symmetric key parameters.
        symmetricKey.Mode = CipherMode.CBC;

        // Generate decryptor from the existing key bytes and initialization 
        // vector. Key size will be defined based on the number of the key 
        // bytes.
        ICryptoTransform decryptor = symmetricKey.CreateDecryptor(
                                                         keyBytes, 
                                                         initVectorBytes);

        // Define memory stream which will be used to hold encrypted data.
        MemoryStream  memoryStream = new MemoryStream(cipherTextBytes);

        // Define cryptographic stream (always use Read mode for encryption).
        CryptoStream  cryptoStream = new CryptoStream(memoryStream, 
                                                      decryptor,
                                                      CryptoStreamMode.Read);

        // Since at this point we don't know what the size of decrypted data
        // will be, allocate the buffer long enough to hold ciphertext;
        // plaintext is never longer than ciphertext.
        byte[] plainTextBytes = new byte[cipherTextBytes.Length];

        // Start decrypting.
        int decryptedByteCount = cryptoStream.Read(plainTextBytes, 
                                                   0, 
                                                   plainTextBytes.Length);

        // Close both streams.
        memoryStream.Close();
        cryptoStream.Close();

        // Convert decrypted data into a string. 
        // Let us assume that the original plaintext string was UTF8-encoded.
        string plainText = Encoding.UTF8.GetString(plainTextBytes, 
                                                   0, 
                                                   decryptedByteCount);

        // Return decrypted string.   
        return plainText;
    }
}

/// <summary>
/// Illustrates the use of RijndaelSimple class to encrypt and decrypt data.
/// </summary>
public class RijndaelSimpleTest
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {
        string   plainText          = "Hello, World!";    // original plaintext

        string   passPhrase         = "Pas5pr@se";        // can be any string
        string   saltValue          = "s@1tValue";        // can be any string
        string   hashAlgorithm      = "SHA1";             // can be "MD5"
        int      passwordIterations = 2;                  // can be any number
        string   initVector         = "@1B2c3D4e5F6g7H8"; // must be 16 bytes
        int      keySize            = 256;                // can be 192 or 128

        Console.WriteLine(String.Format("Plaintext : {0}", plainText));

        string  cipherText = RijndaelSimple.Encrypt(plainText,
                                                    passPhrase,
                                                    saltValue,
                                                    hashAlgorithm,
                                                    passwordIterations,
                                                    initVector,
                                                    keySize);

        Console.WriteLine(String.Format("Encrypted : {0}", cipherText));

        plainText          = RijndaelSimple.Decrypt(cipherText,
                                                    passPhrase,
                                                    saltValue,
                                                    hashAlgorithm,
                                                    passwordIterations,
                                                    initVector,
                                                    keySize);

        Console.WriteLine(String.Format("Decrypted : {0}", plainText));
    }
}