0

有人可以帮助解释以下内容吗?在附件代码中,当输入要加密的文本与 ICryptoTransform 的 InputBlockSize 完全对齐时,结果比输入大 1 个块。为什么会这样,以及如何避免这种情况。我需要解密另一个系统(iOS6)上的数据,其中未添加或预期此附加块。

代码的输出就在代码段之后。



    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Security.Cryptography;
    using System.Text;
    using System.Threading.Tasks;

    namespace TestCryptoAPI
    {
             class Program
             {
                     private static AesCryptoServiceProvider _cryptoServiceProvider;

                     static void Main(string[] args)
                     {
                              var encryptionKey = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xae };
                              var initializationVector = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5 };
                              _cryptoServiceProvider = new AesCryptoServiceProvider();

                              _cryptoServiceProvider.Key = encryptionKey;
                              _cryptoServiceProvider.IV = initializationVector;
                              _cryptoServiceProvider.Mode = CipherMode.CFB;
                              _cryptoServiceProvider.Padding = PaddingMode.PKCS7;

                              Console.WriteLine("_cryptoServiceProvider.BlockSize={0}", _cryptoServiceProvider.BlockSize);
                              ICryptoTransform encryptor = _cryptoServiceProvider.CreateEncryptor();
                              Console.WriteLine("encryptor.InputBlockSize={0}, encryptor.OutputBlockSize={1}", encryptor.InputBlockSize, encryptor.OutputBlockSize);

                              const string clearText15Chars = "123456789012345";
                              const string clearText16Chars = "1234567890123456";
                              const string clearText31Chars = "1234567890123456789012345678901";
                              const string clearText32Chars = "12345678901234567890123456789012";
                              const string clearText47Chars = "12345678901234567890123456789012345678901234567";
                              const string clearText48Chars = "123456789012345678901234567890123456789012345678";
                              const string clearText63Chars = "123456789012345678901234567890123456789012345678901234567890123";
                              const string clearText64Chars = "1234567890123456789012345678901234567890123456789012345678901234";

                              EncryptAndPrint(clearText15Chars);
                              EncryptAndPrint(clearText16Chars);
                              EncryptAndPrint(clearText31Chars);
                              EncryptAndPrint(clearText32Chars);
                              EncryptAndPrint(clearText47Chars);
                              EncryptAndPrint(clearText48Chars);
                              EncryptAndPrint(clearText63Chars);
                              EncryptAndPrint(clearText64Chars);
                     }

                     private static void EncryptAndPrint(string clearTextChars)
                     {
                              var cypherData = Encrypt(clearTextChars);
                              Console.WriteLine("ClearTextChars.Length={0}, CypherData.Length={1}, {2}", clearTextChars.Length, cypherData.Length, Convert.ToBase64String(cypherData));
                     }

                     private static byte[] Encrypt(string clearText15Chars)
                     {
                              var dataToEncrypt = Encoding.Default.GetBytes(clearText15Chars);
                              ICryptoTransform encryptor = _cryptoServiceProvider.CreateEncryptor();

                              var cypherData = encryptor.TransformFinalBlock(dataToEncrypt, 0, dataToEncrypt.Length);
                              return cypherData;
                     }
             }
    }

输出:

    _cryptoServiceProvider.BlockSize=128
    encryptor.InputBlockSize=16, encryptor.OutputBlockSize=16
    ClearTextChars.Length=15,CypherData.Length=16,u8UVUNITsRswDu+usR3/gA==
    ClearTextChars.Length=16,CypherData.Length=32,u8UVUNITsRswDu+usR3/t7WnO82YSBITPehPTgwYTcg=

    ClearTextChars.Length=31,CypherData.Length=32,u8UVUNITsRswDu+usR3/t5LDd7hM0jYQr5mv9BU/6rE=
    ClearTextChars.Length=32,CypherData.Length=48,u8UVUNITsRswDu+usR3/t5LDd7hM0jYQr5mv9BU/6oK3EUi+F5lNkLmPFLjyIRCz

    ClearTextChars.Length=47,CypherData.Length=48,u8UVUNITsRswDu+usR3/t5LDd7hM0jYQr5mv9BU/6oKUWgdedM8a5BDQMQtWF5eA
    ClearTextChars.Length=48,CypherData.Length=64,u8UVUNITsRswDu+usR3/t5LDd7hM0jYQr5mv9BU/6oKUWgdedM8a5BDQMQtWF5e5HTHV4UCSuS5YsTlhNZwt+g==

    ClearTextChars.Length=63,CypherData.Length=64,u8UVUNITsRswDu+usR3/t5LDd7hM0jYQr5mv9BU/6oKUWgdedM8a5BDQMQtWF5e5NMSh/6GlzSMfscnk1Sc4bg==
    ClearTextChars.Length=64,CypherData.Length=80,u8UVUNITsRswDu+usR3/t5LDd7hM0jYQr5mv9BU/6oKUWgdedM8a5BDQMQtWF5e5NMSh/6GlzSMfscnk1Sc4W+Pb0ijEWKmgNJfGsQigc6A=
    按任意键继续 。. .

4

1 回答 1

3

您正在使用 PKCS #7 填充。此方案将始终将字节添加到明文中,即使它已经是块对齐的。

在您的情况下,明文被填充了十六个字节,值为“16”。因此,您会在密文中获得一个额外的块。

如果您的其他代码没有预料到这一点,那么它没有使用 PKCS #7 填充。或者实现被破坏。

于 2013-08-06T19:37:25.827 回答