node.js - Swift 加密和 NodeJS 解密产生不一致的结果
问题描述
我对 Crypto 不是很熟悉,但我确实确保 iv 长度缓冲区返回正确的长度,使用的加密密钥是相同的。
NodeJS 的预期结果是 16 个随机字节的预设 IV 长度 + encryptedText 生成的aes-256-cbc
组合成长度为 64 的十六进制字符串。
在 Node 中测试加密并对其进行解密会产生预期的结果。但是,当 iOS 发送有效负载时,它会解密为未知字符串。
但是,当 iOS 加密并发送数据时。我无法解密它以获得预期的字符串。
对于 iOS,我正在使用 CommonCryto 库
import CommonCrypto
struct AES {
private let key: String
init?(key: String) {
guard key.count == kCCKeySizeAES256 else {
debugPrint("Error: Failed to set a key.")
return nil
}
self.key = key
}
func encrypt(string: String) -> Data? {
return crypt(data: string.data(using: .utf8), operation: kCCEncrypt)
}
private func crypt(data: Data?, operation: Int) -> Data? {
guard let data = data else {
return nil
}
var ivBytes: [UInt8]
var inBytes: [UInt8]
var outLength: Int
if operation == kCCEncrypt {
ivBytes = [UInt8](repeating: 0, count: kCCBlockSizeAES128)
guard kCCSuccess == SecRandomCopyBytes(kSecRandomDefault, ivBytes.count, &ivBytes) else {
fatalError("IV creation failed!")
}
inBytes = Array(data)
outLength = data.count + kCCBlockSizeAES128
} else {
ivBytes = Array(Array(data).dropLast(data.count - kCCBlockSizeAES128))
inBytes = Array(Array(data).dropFirst(kCCBlockSizeAES128))
outLength = inBytes.count
}
var outBytes = [UInt8](repeating: 0, count: outLength)
var bytesMutated = 0
guard kCCSuccess == CCCrypt(CCOperation(operation), CCAlgorithm(kCCAlgorithmAES), CCOptions(kCCOptionPKCS7Padding), Array(key), key.count, &ivBytes, &inBytes, inBytes.count, &outBytes, outLength, &bytesMutated) else {
fatalError("Cryptography operation \(operation) failed")
}
var outData = Data(bytes: &outBytes, count: bytesMutated)
if operation == kCCEncrypt {
ivBytes.append(contentsOf: Array(outData))
outData = Data(ivBytes)
}
return outData
}
}
以及我如何在 NodeJS 中解密:
const decrypt = functions.https.onCall(async (data, context) => {
const uid = context && context.auth && context.auth.uid;
if(!uid) {
return sendErrorResponse({
payload: 'Unauthorised',
statusCode: 401,
});
}
const { password } = data;
const MID = password.length / 2;
const textPart = [password.slice(0,MID),password.slice(MID)];
const iv = Buffer.from(textPart.shift(),'hex');
const encryptedText = Buffer.from(textPart.join(),'hex');
const decipher = crypto.createDecipheriv('aes-256-cbc', encryptionKey, iv).setAutoPadding(false);
let decrypted = decipher.update(encryptedText);
decrypted = Buffer.concat([decrypted, decipher.final()]);
return decrypted.toString();
});
解决方案
寻找跨板式AES 加密