0

这是一个令人头疼的问题。它涉及加密,使其特别粗糙!

我有使用 CCCrypt 到 AES 128 的 Objective-C 代码加密我使用协议缓冲区和 AsyncSockets 发送的 iPhone 上的消息。iOS代码如下:

- (NSData *)AES128EncryptWithKey:(const char *)keyPtr {

    NSUInteger dataLength = [self length];

    //See the doc: For block ciphers, the output size will always be less than or 
    //equal to the input size plus the size of one block.
    //That's why we need to add the size of one block here
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);

    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                          keyPtr, kCCKeySizeAES128, // oorspronkelijk 256
                                          keyPtr /* initialization vector (optional) */,
                                          [self bytes], dataLength, /* input */
                                          buffer, bufferSize, /* output */
                                          &numBytesEncrypted);
    if (cryptStatus == kCCSuccess) {
        //the returned NSData takes ownership of the buffer and will free it on deallocation
        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    } else {
        free(buffer); //free the buffer;
        return nil;
    }
}

我将 AES 托管对象定义如下:

    AesManaged AES = new AesManaged();
    AES.Padding = PaddingMode.PKCS7;
    var shared = /* a shared key */
    var salt = shared + DH.P;
    Rfc2898DeriveBytes deriveBytes = /* derived bytes from shared */
    byte[] ekey = deriveBytes.GetBytes(16);
    byte[] eiv = ekey;
    AES.Key = ekey;
    AES.IV = eiv;

然后,我使用以下 C# .Net 代码在我的服务器上解密这些数据:

public byte[] Decrypt(byte[] encryptedData)
{
    byte[] dec = null;
    MemoryStream ms = new MemoryStream(encryptedData);
    using (CryptoStream cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Read))
    {
         BinaryReader reader = new BinaryReader(cs);
         dec = reader.ReadBytes(encryptedData.Length);
         reader.Close();
    }
    return dec;
}

当我在 iOS 模拟器中运行以及从 Xcode 调试到设备本身时,这非常有效。但是,当我创建应用程序的分发包(IPA 文件)并将其部署到设备时,我在服务器上收到此异常:

System.Security.Cryptography.CryptographicException: Padding is invalid and cannot be removed.

我发送的导致此问题的数据的未加密数据长度为 4,从而创建了 16 的加密大小。由于我相信这是 AES 块大小,这似乎是正确的。调试日志显示这是已部署应用程序和模拟器上消息的大小。所以大小似乎没有错。

阅读有关此异常的信息向我表明,填充的创建方式存在问题。但是,为什么在设备上部署与通过调试器或模拟器运行时会有所不同?

提前致谢。几天来我一直在试图解决这个问题,这阻止了我让我的应用程序被 Apple 测试。

4

1 回答 1

0

几个注意事项:

a)您能否显示从 iOS 上的共享密钥派生加密密钥的代码。

您为 .NET 显示了此代码,但没有为 iOS 显示。

b) 确保 iOS 上的 keyPtr 实际上包含 128 位(16 字节)。如果由于任何原因它包含较少,您可能对此有疑问

c) 我不建议将 keyPtr 作为 IV 传递。一般来说,这是一个不好的做法。您应该为每个加密文件创建新的唯一 IV。

出于测试目的,您可以将其设置为 NULL(少一个变量需要担心)。

d) 您能否展示派生加密密钥的整个 .NET 代码。有几点不清楚:

  • 什么是DH.P?

  • Rfc2898DeriveBytes derivedBytes = /* 从共享中派生的字节 */ 据我所知,应该有类似 new Rfc2898DeriveBytes(pwd, salt); 你用什么作为密码和盐并不明显。

于 2012-09-26T21:27:00.060 回答