【问题标题】:AES: encrypt using CCCrypt() method and decrypt using C#, the output is wrongAES:使用 CCCrypt() 方法加密并使用 C# 解密,输出错误
【发布时间】:2016-04-20 08:02:56
【问题描述】:

使用CCCrypt()方法加密,然后在C#中解密。但输出与原始纯文本不同。

密钥长度为 256 位,IV 为默认值。

主要代码如下:

// Encrypt
{
    // the key is 32 bytes (256 bits).
    Byte iv[] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };

    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,        // Operation
                                      kCCAlgorithmAES128, // Algorithm
                                      kCCOptionPKCS7Padding, // Option
                                      keyPtr,                // key
                                      kCCKeySizeAES256,      // key length
                                      iv, /* initialization vector (optional) */
                                      [self bytes],    // plain text
                                      dataLength, /* input */
                                      buffer,
                                      bufferSize, /* output */
                                      &numBytesEncrypted); //dataOutMove
    if (cryptStatus == kCCSuccess) {
        NSData *encryptedData = [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
        NSString *encryptedString = [encryptedData base64Encoding];
}

// Decrypted
{
    byte[] _key1 = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
    public static string AESDecrypt(string encryptedString, string key)
    {
        AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
        aes.BlockSize = 128;
        aes.KeySize = 256;
        aes.IV = _key1;
        aes.Key = Encoding.UTF8.GetBytes(key);
        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.PKCS7;

        // Convert Base64 strings to byte array
        byte[] src = System.Convert.FromBase64String(encryptedString);

        // decryption
        using (ICryptoTransform decrypt = aes.CreateDecryptor())
        {
            byte[] dest = decrypt.TransformFinalBlock(src, 0, src.Length);
            return Encoding.UTF8.GetString(dest);
        }
    }
}

编辑: 我发现原因是keyPtr。在加密过程中,我会像这样提前处理密钥:

char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused)
bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding) [key
getCString:keyPtr maxLength:sizeof(keyPtr)
encoding:NSUTF8StringEncoding];

现在,我像这样修改这些代码:

NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
NSUInteger keyLength = [keyData length];
Byte *keyPtr= (Byte *)malloc(keyLength);
memcpy(keyPtr, [keyData bytes], keyLength);

然后我得到了正确的输出。 虽然问题没有了,但我真的不知道以前的版本有什么问题。

【问题讨论】:

  • C# 中的 _key1 与 OSX 中的 IV 是否相同?
  • 是的,IV 是同一个常数。
  • keyPtr 怎么样,在 OSX 中也是一个 UTF8 字符串作为字节数组吗?
  • @nvoigt,我已经编辑了我的问题。
  • @GateLuma 您出错的部分是您将密钥作为字符串处理。密码是字符串,密钥不是,它们是字节数组(或您的环境中的NSData)。它们可能包含任何字节值,包括零。当涉及到无效编码和不可打印的字符时,将它们作为字符串处理会给您带来麻烦。另一方面,如果您的密钥看起来不像具有随机值的字节,那么您做错了。查找 PBKDF2 或生成真正的随机密钥。

标签: c# macos encryption aes


【解决方案1】:

即使是一个小错误,加密货币的设计也会严重失败。您需要明确检查键是否逐字节相同(检查字节,而不是字符)。 IV 也一样。您正在 CBC 模式下解码。你确定加密是CBC模式吗?它没有在您的代码中明确设置。与填充相同。你确定加密方式是使用PKCS7吗?

一般不要依赖默认设置,而是在代码中明确设置。

最后一点,您是否在两边都使用相同的字节 字符转换。同样,最好明确说明您正在使用什么。例如,UTF-8 文本可能带有一个 UTF-8 转换将忽略的初始 BOM,但字节中将包含不同的转换。

【讨论】:

  • 我已经解决了这个问题,我编辑了这个问题。但是,我不知道真正的季节会导致问题。
【解决方案2】:

我在查看一些代码时遇到了同样的问题 - 由 CCCrypt 加密并由另一个工具解密的数据 - 没有产生相同的明文。我追查到未能正确生成密钥。就是这一行:

[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

如果 "key" 的 CString 版本长于 kCCKeySizeAES256 字节,则 key:getCString 将返回 "NO"(因为它不适合提供的缓冲区)并且不会触及 keyPtr 指向的缓冲区,导致在一个实际上是所有 NUL 字节的键中(来自 bzero 函数)。

您的替换代码,使用 [key dataUsingEncoding] 不会遇到这个问题,因为它将创建一个 NSData 对象,其大小与存储字符串所需的一样大。但是,它会遇到 key 不够大的问题,除非你能保证传入的 key 足够长。

不推荐使用纯文本键。如果您有纯文本“密码短语”,则使用密钥派生函数将其转换为二进制序列。 “黄金标准”是 PBKDF2,但即使执行 SHA2-256 也比输入纯文本要好。 SHA2-256 会给你 32 个字节。 (SHA-1 不够,因为它只有 20 个字节)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-30
    • 2011-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多