【问题标题】:Last block generated differently for AES 128 Encryption (between iOS and .NET)最后一个块为 AES 128 加密(在 iOS 和 .NET 之间)生成不同
【发布时间】:2012-03-13 21:47:39
【问题描述】:

我在将 .NET C# AES 128 加密转换为 iOS (iPhone) 时遇到问题。除最后一个块外,所有内容均正确生成。对 xfrm.TransformFinalBlock 的最终调用与我从 iOS 代码(使用 CCCryptorFinal)得到的不同。我对 BlockSize、Key 和 IV 使用相同的参数。我还缺少什么?谢谢。

Obj-C

CCCryptorStatus ccStatus = kCCSuccess;


CCCryptorRef thisEncipher = NULL;

// Create and Initialize the crypto reference.
ccStatus = CCCryptorCreate(kCCEncrypt, 
                           kCCAlgorithmAES128, 
                           kCCOptionPKCS7Padding, 
                           szKey,
                           kCCKeySizeAES128, 
                           iv, 
                           &thisEncipher
                           );

// Calculate byte block alignment for all calls through to and including final.
int bufferPtrSize = CCCryptorGetOutputLength(thisEncipher, InputLength, true);

unsigned char *szResult = (unsigned char *)malloc(bufferPtrSize+1);

memset(szResult, 0x00, bufferPtrSize+1);

while (dataEncrypted < dataToEncrypt)
{
    bool final = (dataToEncrypt - dataEncrypted) <= lrcEncryptionBlockSize;

    if (final)
    {
        // Finalize everything to the output buffer.

        ccStatus = CCCryptorFinal(thisEncipher,
                                  szResult + dataEncrypted,
                                  bufferPtrSize - dataEncrypted,
                                  pOutSize
                                  );


        dataEncrypted += *pOutSize;

        for(int c=0;c<dataEncrypted;++c)
        {
            printf("\n%d => %d\n", c, szResult[c]);
        }

        success = true;
        break;
    }
    else
    {

    // Actually perform the encryption or decryption.
        ccStatus = CCCryptorUpdate( thisEncipher,
                                   szInput+cb,
                                   lrcEncryptionBlockSize,
                                   szResult+dataEncrypted,
                                   bufferPtrSize - dataEncrypted,
                                   pOutSize
                                   );   


        dataEncrypted += *pOutSize;

        cb += lrcEncryptionBlockSize;

    }
}

if (thisEncipher) {
    (void) CCCryptorRelease(thisEncipher);
    thisEncipher = NULL;
}

C#

        AesManaged aesAlg = new AesManaged();
        ICryptoTransform xfrm;

        aesAlg.IV = GenerateIV();
        aesAlg.Key = "1111111111111111";
        aesAlg.BlockSize = 128;

        xfrm = aesAlg.CreateEncryptor();

        while (dataEncrypted < dataToEncrypt)
        {
            bool final = (dataToEncrypt - dataEncrypted) <= lrcEncryptionBlockSize;
            int nbytes = !final ? lrcEncryptionBlockSize : (int)(dataToEncrypt - dataEncrypted); 

            if (final)
            {
                byte[] finalblock = xfrm.TransformFinalBlock(message, cb, nbytes);
                Buffer.BlockCopy(finalblock, 0, message, cb, lrcEncryptionBlockSize);
                success = true;
                break;
            }
            else
            {
                dataEncrypted += (uint)xfrm.TransformBlock(message, cb, nbytes, message, cb);
                cb += lrcEncryptionBlockSize;
            }
        }

        xfrm.Dispose();
        aesAlg.Clear();

【问题讨论】:

  • 't 可能是 Erik 建议的填充,否则您可能会查看行尾、空终止字节等。一点点的不同,至少会产生一大块的不同。
  • iOS 使用 PKCS7 填充内容,但 AesManaged(默认情况下)也是如此。要发现问题,请在每个实现中加密一些文本。然后使用 AesManaged & PaddingMode = None 解密。检查尾随字节,您可能会找到罪魁祸首。此外,您可能会对这个 Q/A 感兴趣:stackoverflow.com/questions/6461419/…

标签: iphone .net encryption aes


【解决方案1】:

如果只有最后一个块不同,那么区别可能是它们使用了不同的填充。第一个示例使用 PKCS7,但我看不到第二个示例使用什么。

【讨论】:

  • 添加 Padding 属性会生成相同的字节数组。看起来 PKCS#7 是默认值。
  • 解密两个输出而不删除填充,看看它们是否/如何不同。
猜你喜欢
  • 1970-01-01
  • 2013-01-16
  • 2017-05-16
  • 1970-01-01
  • 2013-12-07
  • 1970-01-01
  • 2015-04-10
  • 2014-06-03
  • 2012-02-23
相关资源
最近更新 更多