【问题标题】:AES encryption on iOS with base64 key from CryptoJS使用 CryptoJS 的 base64 密钥在 iOS 上进行 AES 加密
【发布时间】:2017-08-28 22:29:46
【问题描述】:

我正在使用 CryptoJS 生成和导出密钥:

const password = crypto.lib.WordArray.random(128 / 8);
const salt = crypto.lib.WordArray.random(128 / 8);
const encryptionKey = crypto.PBKDF2(password, salt, {keySize: 128 / 32});
return encryptionKey.toString();

现在我正在尝试用 iOS 上的密钥加密一些数据:

const char *s = [encryptionKey cStringUsingEncoding:NSASCIIStringEncoding];
NSData *keyData= [NSData dataWithBytes:s length:strlen(s)];

NSMutableData *ivData = [NSMutableData dataWithLength:kCCBlockSizeAES128];
SecRandomCopyBytes(kSecRandomDefault, kCCBlockSizeAES128, ivData.mutableBytes);
NSData *iv = [NSData dataWithData:ivData];

size_t outLength;

NSMutableData *cipherData = [NSMutableData dataWithLength:dataString.length + kCCBlockSizeAES128];
CCCrypt(kCCEncrypt, // operation
    kCCAlgorithmAES128, // Algorithm
    kCCOptionPKCS7Padding, // options
    keyData.bytes, // key
    keyData.length, // keylength
    iv.bytes,// iv
    jsonData.bytes, // dataIn
    jsonData.length, // dataInLength,
    cipherData.mutableBytes, // dataOut
    cipherData.length, // dataOutAvailable
    &outLength); // dataOutMoved

    cipherData.length = outLength;

NSString *cipherText = [cipherData base64EncodedStringWithOptions:NSUTF8StringEncoding];
NSString *ivText = [iv base64EncodedStringWithOptions:NSUTF8StringEncoding];

return [ivText stringByAppendingString:cipherText]

到目前为止,这一切都有效。尝试使用 CryptoJS 解密数据失败:

const iv = crypto.enc.Base64.parse(message.substr(0, 24));
const encrypted = crypto.enc.Base64.parse(message.substring(24));

const decrypted = crypto.AES.decrypt(encrypted, encryptionKey, {
  iv: iv,
  padding: crypto.pad.Pkcs7,
  mode: crypto.mode.CBC
});
console.log(decrypted.toString(crypto.enc.Utf8))

问题似乎在于将密钥从 CryptoJS 传递到 iOS。传递给 CCCrypt 的正确格式是什么?

【问题讨论】:

  • 1.您在哪里可以找到crypto.PBKDF2 的文档? 2.keySize: 128 / 32是什么参数,为什么取值4
  • 3.提供示例encryptionKeypassword。 4.提供示例明文数据、加密数据、错误解密数据、加密IV和恢复解密iv。
  • 代码基于这里的例子:robnapier.net/aes-commoncrypto

标签: ios objective-c encryption aes cryptojs


【解决方案1】:

base64EncodedStringWithOptions 的选项不正确,会在 Base64 编码的 iv 和加密数据中添加行尾字符。

您不需要行尾选项,默认情况下不插入行尾。只需指定0

NSString *cipherText = [cipherData base64EncodedStringWithOptions:0];
NSString *ivText = [iv base64EncodedStringWithOptions:0];

选项 请注意,NSUTF8StringEncoding 不是方法 base64EncodedStringWithOptions 的编码选项。选项有:

NSDataBase64Encoding64CharacterLineLength
NSDataBase64Encoding76CharacterLineLength
NSDataBase64EncodingEndLineWithCarriageReturn
NSDataBase64EncodingEndLineWithLineFeed`

这些都是行分隔符选项。

【讨论】:

    【解决方案2】:

    我的原始代码包含三个错误。

    1. 生成的字符串需要按照 zaph 的建议不使用任何参数进行编码:

      NSString *cipherText = [cipherData base64EncodedStringWithOptions:0];
      NSString *ivText = [iv base64EncodedStringWithOptions:0];
      
    2. 为了正确地将加密密钥转换为NSData,我使用here提供的方法并这样调用它:

      NSData *keyData= [self dataFromHexString:encryptionKey];
      
    3. CryptoJS 的decrypt 函数需要这样的对象:

      const encrypted = crypto.enc.Base64.parse(message.substring(24));
      
      const params = {
        ciphertext: encrypted,
        salt: ''
      };
      
      const decrypted = crypto.AES.decrypt(params, crypto.enc.Hex.parse(this.encryptionKey.toString()), {
        iv: iv,
        padding: crypto.pad.Pkcs7,
        mode: crypto.mode.CBC
      });
      
      return decrypted.toString(crypto.enc.Utf8);
      

    感谢您的帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-17
      相关资源
      最近更新 更多