首页 > 解决方案 > Unable to decrypt string encrypted using openssl -aes256 in swift

问题描述

I want to encrypt keys outside application and pass to application. In the app while using those key again have to decrypt string using key which were used while encryption.

Which key to be used while decrypting in Swift? "FUUU" or key generated by openssl command

On mac I am generating encrypted string using openssl -aes256, but while decrypted in swift it always returns nil. If I set key generated by openssl then it gives error "Error: Failed to set a key." and "Error: Failed to set an initial vector."

echo -n "TEST1" | openssl enc -aes256 -k FUUU -nosalt -a -p

Console Output

key=59C12FFF74992ED40F4DF80A56AB55AE7C513B17CB4B8CF8342E9444C7F7AF3B
iv =0BEE68AD25123B7076B91A5AFB549E33
bYbkQJcDFZt3y3UQEMbEeg==

Decrypt in Swift

let encryptedMessage = "bYbkQJcDFZt3y3UQEMbEeg==".data(using: .utf8)!
let key256 = "59C12FFF74992ED40F4DF80A56AB55AE7C513B17CB4B8CF8342E9444C7F7AF3B" // 32 bytes for AES256
let iv = "0BEE68AD25123B7076B91A5AFB549E33" // 16 bytes for AES128

let aes256 = AES(key: key256, iv: iv)

let decryptedMessage256 = aes256?.decrypt(data: encryptedMessage)
print("Decrypted: \(String(bytes: decryptedMessage256, encoding: .utf8))")

AES

import CommonCrypto

struct AES {

// MARK: - Value
// MARK: Private
private let key: Data
private let iv: Data

// MARK: - Initialzier
init?(key: String, iv: String) {
    guard key.count == kCCKeySizeAES128 || key.count == kCCKeySizeAES256, let keyData = key.data(using: .utf8) else {
        debugPrint("Error: Failed to set a key.")
        return nil
    }

    guard iv.count == kCCBlockSizeAES128, let ivData = iv.data(using: .utf8) else {
        debugPrint("Error: Failed to set an initial vector.")
        return nil
    }

    self.key = keyData
    self.iv  = ivData
}

// MARK: - Function
// MARK: Public
func encrypt(string: String) -> Data? {
    return crypt(data: string.data(using: .utf8), option: CCOperation(kCCEncrypt))
}

func decrypt(data: Data?) -> String? {
    guard let decryptedData = crypt(data: data, option: CCOperation(kCCDecrypt)) else { return nil }
    return String(bytes: decryptedData, encoding: .utf8)
}

func crypt(data: Data?, option: CCOperation) -> Data? {
    guard let data = data else { return nil }

    let cryptLength = [UInt8](repeating: 0, count: data.count + kCCBlockSizeAES128).count
    var cryptData   = Data(count: cryptLength)

    let keyLength = [UInt8](repeating: 0, count: kCCBlockSizeAES128).count
    let options   = CCOptions(kCCOptionPKCS7Padding)

    var bytesLength = Int(0)

    let status = cryptData.withUnsafeMutableBytes { cryptBytes in
        data.withUnsafeBytes { dataBytes in
            iv.withUnsafeBytes { ivBytes in
                key.withUnsafeBytes { keyBytes in
                    CCCrypt(option, CCAlgorithm(kCCAlgorithmAES), options, keyBytes, keyLength, ivBytes, dataBytes, data.count, cryptBytes, cryptLength, &bytesLength)
                }
            }
        }
    }

    guard UInt32(status) == UInt32(kCCSuccess) else {
        debugPrint("Error: Failed to crypt data. Status \(status)")
        return nil
    }

    cryptData.removeSubrange(bytesLength..<cryptData.count)
    return cryptData
}
}

标签: iosswiftopensslaes

解决方案


恐怕桌面密码框架与移动密码框架不匹配,这是 iOS 上的常见问题,您必须创建自己的密码才能匹配它。

但另一方面你可以使用CryptoSwift,它非常可靠,我个人使用它,它确实与服务器密码匹配,所以我认为它可以解决你的问题。


推荐阅读