AES加密 C#

3

编辑:我已经在底部加入了我的哈希码。

我正在创建一个解决方案的消息完整性密钥遇到了一些问题。为了正确使用它,我需要使用以下设置。

模式:ECB 密钥大小:256 块大小:128 填充:PKCS7

我正在使用从文件生成的32字节密钥,以及空白 IV,因为我了解 ECB 不需要 IV。

我的问题是,我期望在编码之前获得 48 字节的输出,但我收到的是 64 字节的输出。

下面显示了我尝试实现此操作的一些代码,但我没有取得太大的成功。

public static string Encrypt(string hash) {

        // Create a new instance of the AesManaged
        // class.  This generates a new key and initialization 
        // vector (IV).
        using (AesManaged myAes = new AesManaged()) {

            myAes.Key = File.ReadAllBytes("keyfile");
            myAes.Mode = CipherMode.ECB;
            myAes.IV = new byte[16] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
            myAes.KeySize = 256;
            myAes.BlockSize = 128;
            myAes.Padding = PaddingMode.PKCS7;

            // Encrypt the string to an array of bytes.
            byte[] encrypted = EncryptStringToBytes_Aes(hash, myAes.Key, myAes.IV);

            // Decrypt the bytes to a string.
            string roundtrip = DecryptStringFromBytes_Aes(encrypted, myAes.Key, myAes.IV);

            //Display the original data and the decrypted data.
            Console.WriteLine("Original:   {0}", hash);
            Console.WriteLine("Round Trip: {0}", roundtrip);

            // Encode
            string encoded = Convert.ToBase64String(encrypted);

            Console.WriteLine("Encoded:    {0}", encoded);
            return encoded;
        }
    }

    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");
        byte[] encrypted;
        // Create an AesManaged object
        // with the specified key and IV.
        using (AesManaged aesAlg = new AesManaged()) {
            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.
            using (MemoryStream 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);
                    }
                    encrypted = msEncrypt.ToArray();
                }
            }
        }
        // Return the encrypted bytes from the memory stream.
        return encrypted;
    }

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

        // Declare the string used to hold
        // the decrypted text.
        string plaintext = null;

        // Create an AesManaged object
        // with the specified key and IV.
        using (AesManaged aesAlg = new AesManaged())
        {
            aesAlg.Key = Key;
            aesAlg.IV = IV;

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

            // Create the streams used for decryption.
            using (MemoryStream msDecrypt = new MemoryStream(cipherText))
            {
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                    {

                        // Read the decrypted bytes from the decrypting stream
                        // and place them in a string.
                        plaintext = srDecrypt.ReadToEnd();
                    }
                }
            }

        }

        return plaintext;

    }

        public static string getHashSha256(string text) {
        byte[] bytes = Encoding.UTF8.GetBytes(text);
        SHA256Managed hashstring = new SHA256Managed();
        byte[] hash = hashstring.ComputeHash(bytes);
        string hashString = string.Empty;
        foreach (byte x in hash) {
            hashString += String.Format("{0:x2}", x);
        }
        return hashString;
    }

1
当然,我正在使用这个哈希进行测试。41a60829599a584da138ba4bab34dbdb3eb034b934bf9b6749ee1b66e570e6bf - RLW
4
我认为不会,但这可能有助于延迟它们的到来 :) - RLW
1
你为什么要考虑使用ECB呢? - Remus Rusanu
1
密钥大小与输出大小无关。 - ntoskrnl
1
好的,如果是这样的话,我的输入始终保持不变,因为它是SHA-256哈希的结果。所以我假设是AES设置决定了算法的输出? - RLW
显示剩余10条评论
1个回答

2

PKCS #7 填充方式定义了在所有情况下都会添加填充。当明文长度是块大小的倍数时,会添加一个完整的填充块。这就是为什么当明文长度为 48 字节时,密文长度为 64 字节的原因。


1
谢谢您。我也有同样的印象。然而,这个AES的输入来自于SHA-256哈希的结果,它总是会有64个字节。我是否能够从该哈希中得到一个48字节的AES结果呢? - RLW
1
SHA-256生成32字节的哈希值。再加上16字节的填充,结果为48字节。 - ntoskrnl
1
好的,填充是由SHA-256算法添加的吗?也许我用SHA填充了两次,然后再用AES填充一次,导致输出比预期的要长? - RLW
1
好的,我从SHA-256生成了一个32字节的输入。理论上,这应该会导致AES输出32+16(填充)= 48字节?但是我的代码目前产生了80个字节... - RLW
1
好的,那么我应该使用哪种编码方式来将32个字节保持为32个字符? - RLW
显示剩余5条评论

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