使用CryptoJS加密和从Objective-C解密

Encrypt with CryptoJS and decrypt from Objective-C

本文关键字:Objective-C 解密 CryptoJS 加密 使用      更新时间:2023-09-26

在两个应用程序之间的通信中,我想用JavaScript加密一条信息,并使用固定密钥对来自Objective-C客户端的消息进行解密(只是为了基本的安全性)。

加密工作良好:

var command = "mjallo";
var crypto_key = CryptoJS.enc.Base64.parse('280f8bb8c43d532f389ef0e2a5321220');
var crypto_iv  = CryptoJS.enc.Base64.parse("CC0A69779E15780A");
// Encrypt and encode
var encrypted = CryptoJS.AES.encrypt(command, crypto_key, {iv: crypto_iv}).toString();
var encrypted_and_encoded = btoa(encrypted);
// encrypted_and_encoded => 'dFBQVDZZS3dGSktoa0J3Y1NQOElpZz09'
// Confirms that decrypt works with CryptoJS:
// Decode and decrypt
var decrypted = CryptoJS.AES.decrypt(atob(encrypted_and_encoded), crypto_key, {iv: crypto_iv});
// decrypted => 'mjallo'

在经过CryptoJS加密后,您将如何在Objective-c中解码和解密消息?

我尝试使用CocoaSecurity解密,但没有运气。以下是RubyMotion的语法:

  begin
    res = CocoaSecurity.aesDecryptWithBase64('dFBQVDZZS3dGSktoa0J3Y1NQOElpZz09', hexKey: '280f8bb8c43d532f389ef0e2a5321220', hexIv: 'CC0A69779E15780A')
  rescue NSException => e
    p e.reason # => "Length of iv is wrong. Length of iv should be 16(128bits)"
  end

AES支持128位块大小和128位、192位和256位密钥大小。CBC模式的IV值(默认值)应该是128位。

您的编码密钥由32个字符组成。在CryptoJS中,您将其解析为Base64,从而产生192位密钥,但在cocoassecurity中,您假设它是十六进制编码。因为它只包含数字和字母af,它可能是十六进制编码而不是Base64编码。如果假设它是十六进制编码,那么将得到一个有效的AES密钥大小为128位:

var crypto_key = CryptoJS.enc.Hex.parse('280f8bb8c43d532f389ef0e2a5321220');

另一方面,在相同的假设下,您的静脉没有有效的大小。在CBC模式下,AES的IV长度应该是16字节。另外,IV不应该固定在一个静态值上。您需要为每个加密生成一个随机IV。由于IV不必保密,您可以将其与密文一起发送。

var crypto_iv  = CryptoJS.lib.WordArray.random(128/8);
console.log("IV: " + crypto_iv.toString()); // hex encoded

CryptoJS.<Cipher>.encrypt()的结果是一个特殊的可格式化对象。如果在该对象上调用toString(),您将获得Base64编码的密文(当使用基于密码的加密时,可以选择使用盐)。但是然后你通过调用btoa()再次用Base64编码它。你不需要对它进行两次编码。

var encrypted = CryptoJS.AES.encrypt(command, crypto_key, {iv: crypto_iv}).toString();
console.log("Ciphertext (Base64): " + encrypted.toString());
console.log("Ciphertext (Hex): " + encrypted.ciphertext.toString());

据我判断,你的RubyMotion代码看起来很好。


如果您只能更改cocoassecurity代码,那么您将需要

  • 通过将其解码为Base64并将其编码为Hex来重新编码密钥,
  • 向IV十六进制字符串追加16个"0"字符,因为CryptoJS用0x00字节填充IV直到下一个有效IV,
  • 从Base64解码一次密文。

您应该始终验证密文。这可以通过像GCM这样的身份验证模式来完成,也可以通过密文的HMAC来完成。