当输入大小与BlockSize完全对齐时,CryptoAPI cypher数据生成为big

时间:2013-08-06 19:28:32

标签: c# windows encryption ios6 cryptography

有人可以帮忙解释以下内容吗?在附加的代码中,当要加密的输入文本完全对齐时 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=
    Press any key to continue . . .

1 个答案:

答案 0 :(得分:3)

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

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

如果您的其他代码不期望这样,那么它不使用PKCS#7填充。或者实施被打破了。