2

加密“秘密”的字符串

加密后“64c2VjcmV0”

这是正常工作的代码

    let inputNSData: NSData = input.dataUsingEncoding(NSUTF8StringEncoding)!
    let inputBytes: [UInt8] = inputNSData.arrayOfBytes()
    let key: [UInt8] = self.generateArray("secret0key000000") //16
    let iv: [UInt8] = self.generateArray("0000000000000000")  //16
    do {
        let encrypted: [UInt8] = try AES(key: key, iv: iv, blockMode: .CBC).encrypt(inputBytes, padding: PKCS7())    
        let decrypted: [UInt8] = try AES(key: key, iv: iv, blockMode: .CBC).decrypt(encrypted, padding: PKCS7())   
        let decryptNsData: NSData = NSData(bytes: decrypted, length: decrypted.count)     
        let c = decryptNsData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.Encoding64CharacterLineLength)
        let decryptedString: String = NSString(data: decryptNsData, encoding: NSUTF8StringEncoding) as! String
        print("String after decryption\t\(decryptedString)")
    } catch {
        // some error
    }

但我无法使用相同的密钥解密,并且 iv 我收到致命错误:在解开加密字符串的可选值时意外发现 nil

    let key: [UInt8] = self.generateArray("secret0key000000") //16
    let iv: [UInt8] = self.generateArray("0000000000000000")  //16
    let input: String = "64c2VjcmV0"

    var encryptedStrData = NSData(base64EncodedString: input, options: NSDataBase64DecodingOptions())!
    let inputBytes: [UInt8] = encryptedStrData.arrayOfBytes()
    print("String in uint8\(inputBytes)")
    //var keyData = keyStr.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
    //var ivData:NSData = ivStr.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
    do{
    let decryptedTryData = try AES(key: key, iv: iv, blockMode: .CBC).decrypt(inputBytes)
        print(decryptedTryData)
    }
    catch{

    }

我收到致命错误:在打开加密字符串的可选值时意外发现 nil

4

3 回答 3

4

您在不需要时使用 Base64,仅 Base64 编码非字符串数据。

这是第一个测试代码:

let inputBytes: [UInt8] = Array("secret".utf8)
let key:        [UInt8] = Array("secret0key000000".utf8) //16
let iv:         [UInt8] = Array("0000000000000000".utf8)  //16

var encryptedBase64 = ""
do {
    let encrypted: [UInt8] = try AES(key: key, iv: iv, blockMode: .CBC).encrypt(inputBytes, padding: PKCS7())
    let encryptedNSData = NSData(bytes: encrypted, length: encrypted.count)
    encryptedBase64 = encryptedNSData.base64EncodedStringWithOptions([])

    let decrypted: [UInt8] = try AES(key: key, iv: iv, blockMode: .CBC).decrypt(encrypted, padding: PKCS7())
    let result = String(bytes: decrypted, encoding: NSUTF8StringEncoding)!
    print("result\t\(result )")
} catch {
    // some error
}
print("encryptedBase64: \(encryptedBase64)")

输出:

结果:秘密
encryptedBase64:0OCxa0yJszq9MvkrWjn3wg==

let encryptedData = NSData(base64EncodedString: encryptedBase64, options:[])!
print("decodedData: \(encryptedData)")
let encrypted = Array(UnsafeBufferPointer(start: UnsafePointer<UInt8>(encryptedData.bytes), count: encryptedData.length))

do {
    let decryptedData = try AES(key: key, iv: iv, blockMode: .CBC).decrypt(encrypted)
    let decryptedString = String(bytes: decryptedData, encoding: NSUTF8StringEncoding)!
    print("decryptedString: \(decryptedString)")

}
catch{
    // some error
}

输出:

解密字符串:秘密

笔记:

不要使用 CryptoSwift,它不使用内置加密硬件,比 Apple Security.framework Common Crypto慢 400 到 1000 倍。它也没有经过很好的审查和使用未经认证的加密代码。

不要直接使用字符串作为密钥,这是不安全的。而是使用 PBKDK2(基于密码的密钥派生函数)从字符串中派生密钥。

于 2015-10-26T13:23:34.870 回答
0

Base64 字符串必须能被 4 整除。你的不能。您可以使用网站(例如https://www.base64decode.org)来测试您的字符串。

于 2015-10-26T10:17:27.463 回答
0

对于 Swift3(为了避免 UnsafePointer 错误),这对我第二部分(解码 base64 变量)有用:

let encryptedData = NSData(base64Encoded: encryptedBase64, options:[])!
print("decodedData: \(encryptedData)")

let count = encryptedData.length / MemoryLayout<UInt8>.size

// create an array of Uint8
var encrypted = [UInt8](repeating: 0, count: count)
// copy bytes into array
encryptedData.getBytes(&encrypted, length:count * MemoryLayout<UInt8>.size)

do {
    let decryptedData = try AES(key: key, iv: iv, blockMode: .CBC).decrypt(encrypted)
    let decryptedString = String(bytes: decryptedData, encoding: String.Encoding.utf8)!
    print("decryptedString: \(decryptedString)")

}
catch{
    // some error
}
于 2016-11-26T14:34:45.263 回答