javascript - 使用 CryptoJS 加密并使用 Objective-C 解密

标签 javascript objective-c encryption cryptography cryptojs

在两个应用程序之间的通信中,我想在 JavaScript 中加密一条信息,并使用固定 key 从 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 位的 block 大小和 128、192 和 256 位的 key 大小。 CBC 模式(默认)的 IV 应为 128 位。

您的编码 key 由 32 个字符组成。在 CryptoJS 中,您将其解析为 Base64,这会产生 192 位 key ,但在 CocoaSecurity 中,您假设它是十六进制编码的。由于它仅包含数字和字母 af,因此它可能是 Hex 编码而不是 Base64 编码。如果假设它是十六进制编码的,那么将获得 128 位的有效 AES key 大小:

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

另一方面,在相同的假设下,您的 IV 没有有效的大小。对于 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 代码看起来不错。

<小时/>

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

  • 通过将 key 解码为 Base64 并将其编码为十六进制来重新编码 key ,
  • 将 16 个“0”字符附加到 IV 十六进制字符串,因为 CryptoJS 使用 0x00 字节填充 IV 直到下一个有效 IV,
  • 从 Base64 解码一次密文。
<小时/>

您应该始终验证密文。这可以通过 GCM 等身份验证模式或通过密文使用 HMAC 来完成。

关于javascript - 使用 CryptoJS 加密并使用 Objective-C 解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33279933/

相关文章:

javascript - 是否可以独立运行jquery/javascript脚本?

javascript - 将 URI 转换为 Windows 路径格式

javascript - 使用 jquery 访问嵌入对象在 Firefox 3.6 中不起作用

iphone - 将数据从 plist 输出到 NSString

Android AES 和初始化向量

java - 加密和解密(java)

javascript - 计算谷歌电子表格中相同颜色的单元格

iphone - 生产应用程序的客户端崩溃报告

objective-c - 核心文本性能

c - 使用 AES 加密文件