【问题标题】:AES Encryption C#AES 加密 C#
【发布时间】:2013-07-25 01:17:14
【问题描述】:

编辑:在底部添加了我的哈希码。

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

模式:欧洲央行 密钥大小:256 块大小:128 填充:PKCS7

我使用的是一个 32 字节的密钥,它是从一个文件生成的,也是一个空白的 IV,据我所知,ECB 不需要。

我的问题是,我希望在编码之前得到 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;
    }

【问题讨论】:

  • 当然,我正在使用这个哈希进行测试。 41a60829599a584da138ba4bab34dbdb3eb034b934bf9b6749ee1b66e570e6bf
  • 我认为不会,但这可能有助于延迟他们:)
  • 你为什么还要考虑ECB?
  • 密钥大小与输出大小无关。
  • 好的,如果是这种情况,我的输入总是固定的,因为它是 SHA-256 哈希的结果。所以我假设是 AES 设置决定了算法的输出?

标签: c# encryption aes


【解决方案1】:

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

【讨论】:

  • 谢谢你。我也有同样的印象。但是,此 AES 的输入来自 SHA-256 哈希的结果,该哈希始终为 64 字节。在 AES 之后,我什至有可能从该哈希获得 48 字节的结果吗?
  • SHA-256 产生一个 32 字节的散列。使用 16 字节的填充,结果为 48 字节。
  • 好的,SHA-256算法会添加填充吗?也许我用 SHA 填充它两次,然后用 AES 填充它,输出比预期的要长?
  • 好吧,所以我正在从 SHA-256 生成一个 32 字节的输入。这在理论上应该导致 32+16(padding)= 48 来自 AES?我的代码目前产生 80 字节...
  • 好的,那么我应该使用什么形式的编码来保持 32 字节到 32 个字符?
猜你喜欢
  • 2013-04-19
  • 1970-01-01
  • 2022-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-12
  • 2013-08-11
相关资源
最近更新 更多