【问题标题】:How many characters to create a byte array for my AES method?为我的 AES 方法创建一个字节数组需要多少个字符?
【发布时间】:2010-11-06 13:53:45
【问题描述】:

我在这里使用 AES 方法:http://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndaelmanaged.aspx

我想要一个字符串值,我将其转换为字节数组并将其传递给 AES 加密方法。字符串应该包含多少个字符才能产生方法期望的正确字节数组大小?

static byte[] encryptStringToBytes_AES(string plainText, byte[] Key, byte[] IV)
    {
        // Check arguments.
        if (plainText == null || plainText.Length <= 0)
            throw new ArgumentNullException("plainText");
        if (Key == null || Key.Length <= 0)
            throw new ArgumentNullException("Key");
        if (IV == null || IV.Length <= 0)
            throw new ArgumentNullException("Key");

        // Declare the stream used to encrypt to an in memory
        // array of bytes.
        MemoryStream msEncrypt = null;

        // Declare the RijndaelManaged object
        // used to encrypt the data.
        RijndaelManaged aesAlg = null;

        try
        {
            // Create a RijndaelManaged object
            // with the specified key and IV.
            aesAlg = new RijndaelManaged();
            aesAlg.Key = Key;
            aesAlg.IV = IV;

            // Create a decrytor to perform the stream transform.
            ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

            // Create the streams used for encryption.
            msEncrypt = new MemoryStream();
            using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
            {
                using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                {

                    //Write all data to the stream.
                    swEncrypt.Write(plainText);
                }
            }

        }
        finally
        {

            // Clear the RijndaelManaged object.
            if (aesAlg != null)
                aesAlg.Clear();
        }

        // Return the encrypted bytes from the memory stream.
        return msEncrypt.ToArray();

    }

【问题讨论】:

  • 在您的示例中,字符串是“您要加密的内容”。它与“AES 方法所期望的”无关。对称算法需要字节数组、一个密钥和一个初始值,才能开始加密/解密。您将这些作为参数传递给您自己的方法,并将它们直接传递给算法构造函数。因此,您的示例中的字符串可以是任意长度。您可能关心的是如何获得正确大小的密钥和 iv 字节数组,这取决于算法。在 SwDevMan81 的回答中,您可以看到他在您的方法之前初始化了 key+iv。

标签: c# asp.net encryption aes rijndaelmanaged


【解决方案1】:

你需要填充。实际上,您链接的页面有一个关于填充的示例(在 C++ 中)。

使用填充,您可以加密非标准块大小。

【讨论】:

    【解决方案2】:

    纯文本的大小无关紧要。只需确保在 decryptStringFromBytes_AES(byte[] cipherText, byte[] Key, byte[] IV) 方法中使用完全相同的 IV 和 Key 以及加密字节。这将返回给您输入的纯文本。

    例如:

    
    string plain_text = "Cool this works";
    byte[] iv = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                                               0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
    byte[] key = new byte[] { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
                                               0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
    byte[] encrytped_text = encryptStringToBytes_AES(plain_text, key, iv);
    string plain_text_again = decryptStringFromBytes_AES(encrypted_text, key, iv);
    

    在这里您应该看到纯文本和纯文本再次是相同的。现在继续将plain_text 更改为您想要的任何内容,看看这是否正常。

    RijndaelManaged 的​​默认值为:
    块大小:128
    密钥大小:256
    模式:CipherMode.CBC
    填充:PaddingMode.PKCS7

    有效的 IV 大小为:
    128、192、256 位(这是 BlockSize,确保将其设置为您正在使用的大小 IV)
    有效的密钥大小是:
    128、192、256 位(这是 KeySize,请确保将其设置为您正在使用的大小密钥)

    这意味着 byte[] iv 可以是 16、24 或 32 字节(在我上面的示例中它是 16 字节)并且 byte[] 键也可以是 16、24 或 32 字节(在我上面的示例中它的 16 个字节)。

    希望对您有所帮助。

    【讨论】:

    • 请参阅 stackoverflow.com/questions/2919228/... 以获取可用于使用 ConvertFromBase64String 转换为 byte[] 的示例字符串值
    【解决方案3】:

    不要将字符串转换为其 Unicode 字节表示。很难检查正确的长度,并且不能提供足够的随机化。

    您可以执行以下操作:使用key derivation function。您需要一个固定长度的字节数组作为函数的输入。这是Rfc2898 最擅长的。

    所以,创建一个新的 Rfc2898 对象:

    using PBKDF2 = System.Security.Cryptography.Rfc2898DeriveBytes;
    
    class Example {
        byte[] mySalt = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
    
        void Initialize( string password ) {
            PBKDF2 kdf = new PBKDF2( password, mySalt );
            // Then you have your algorithm
            // When you need a key: use:
            byte[] key = kdf.GetBytes( 16 ); // for a 128-bit key (16*8=128)
    
            // You can specify how many bytes you need. Same for IV.
            byte[] iv = kdf.GetBytes( 16 ); // 128 bits again.
    
            // And then call your constructor, etc.
            // ...
        }
    }
    

    有关我如何使用它的示例,请查看my project using Rijndael。我有一个密码步骤,我在其中获取一个字符串并使用上述方法获取密钥和 iv 字节数组。

    【讨论】:

    • 此外,您可以通过这种方法使用随机盐,从相同的密码生成几乎无限的不同密钥。通常的做法是将盐与加密数据一起明文存储。例如,您有密码。您使用 KDF 生成加密密钥+iv。 Rfc2898 类允许您在构造函数中指定“盐大小”。获取它生成的盐。将您的加密数据存储为 (SALT BYTES)+"DELIMETER"+(ENCRYPTED BYTES)。当你需要解码时,你可以取明文密码,使用存储的salt,并且能够重新生成相同的key+iv。
    猜你喜欢
    • 2018-12-12
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-04
    • 1970-01-01
    • 2012-03-12
    • 2019-07-06
    相关资源
    最近更新 更多