CryptoJS与CryptoSwift的AES-CBC加密结果不一致问题求助
CryptoJS与CryptoSwift AES-CBC加密结果不一致问题
我在使用CryptoJS(JavaScript)和CryptoSwift(Swift)实现AES-CBC加密时,两端参数完全一致(密码、盐值、IV、迭代次数等),但加密输出结果不同,无法互相解密。以下是两端代码及输出:
JavaScript代码
var keySize = 256; var ivSize = 128; var iterations = 1000; var message = "Hello World"; var password = "secret"; var ivSfmc = "4963b7334a46352623252955df21d7f3"; var saltSFmc = "e0cf1267f564b362"; var encryptedString = ""; function encrypt(msg, pass) { salt = CryptoJS.enc.Hex.parse(saltSFmc); iv = CryptoJS.enc.Hex.parse(ivSfmc); var key = CryptoJS.PBKDF2(pass, salt, { keySize: keySize / 32, padding: CryptoJS.pad.Pkcs7, iterations: iterations }); var encrypted = CryptoJS.AES.encrypt(msg, key, { iv: iv, mode: CryptoJS.mode.CBC }); encryptedString = encrypted.toString(); return encryptedString; } function decrypt(transitmessage, pass) { iv = CryptoJS.enc.Hex.parse(ivSfmc); salt = CryptoJS.enc.Hex.parse(saltSFmc); var key = CryptoJS.PBKDF2(pass, salt, { keySize: keySize / 32, iterations: iterations }); var decrypted = CryptoJS.AES.decrypt(encrypted, key, { iv: iv, padding: CryptoJS.pad.Pkcs7, mode: CryptoJS.mode.CBC }) return decrypted; } var encrypted = encrypt(message, password); var decrypted = decrypt(encryptedString, password);
JavaScript输出
Encrypted: ndLxNDM5BwSeqNfXAQ5P3g==
Decrypted: Hello World
Swift代码
import UIKit import CryptoSwift class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() do { let password: [UInt8] = Array("secret".utf8) let salt = Array(hex: "e0cf1267f564b362") let key = try PKCS5.PBKDF2( password: password, salt: salt, iterations: 1000, keyLength: 32, /* AES-256 */ variant: .sha256 ).calculate() let iv = Array(hex: "4963b7334a46352623252955df21d7f3") let aes = try AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7) let inputData = Array("Hello World".utf8) let encryptedBytes = try aes.encrypt(inputData) let encryptedData = Data(encryptedBytes) print(encryptedData.base64EncodedString()) let decryptedBytes = try aes.decrypt(encryptedData.bytes) let decryptedData = Data(decryptedBytes) print(String(bytes: decryptedData, encoding: .utf8)!) } catch ( let error) { print(error) } } }
Swift输出
Encrypted: n05I/Ub/GC/mzQRmlNTl7w==
Decrypted: Hello World
问题原因与解决方案
核心原因
问题出在PBKDF2密钥派生时使用的哈希算法不一致:
- CryptoJS的
PBKDF2方法默认采用SHA-1作为伪随机函数(PRF) - Swift代码中明确指定了
variant: .sha256,导致两端生成的密钥完全不同,最终加密结果无法匹配。
修正方案(二选一即可)
方案1:修改CryptoJS代码,指定PBKDF2使用SHA256
在PBKDF2的配置参数中添加hasher: CryptoJS.algo.SHA256,确保和Swift端算法一致:
// 加密和解密函数中的密钥生成部分都需要修改 var key = CryptoJS.PBKDF2(pass, salt, { keySize: keySize / 32, padding: CryptoJS.pad.Pkcs7, iterations: iterations, hasher: CryptoJS.algo.SHA256 // 新增该行指定SHA256 });
方案2:修改Swift代码,将PBKDF2的哈希算法改为SHA1
把PBKDF2的variant参数改为.sha1,匹配CryptoJS的默认行为:
let key = try PKCS5.PBKDF2( password: password, salt: salt, iterations: 1000, keyLength: 32, /* AES-256 */ variant: .sha1 // 修改为SHA1 ).calculate()
验证
任选一种方案修改后,两端生成的加密字符串会完全一致,即可实现互相解密。
内容的提问来源于stack exchange,提问作者mangesh
相关产品推荐
相关产品推荐

