Не удалось расшифровать строку base64String с помощью CryptoSwift
Строка для шифрования "секрет"
после шифрования "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
}
но я не могу расшифровать, используя тот же ключ, и я получаю фатальную ошибку: неожиданно обнаружил ноль при развертывании необязательного значения для зашифрованной строки
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{
}
Я получаю фатальную ошибку: неожиданно обнаружил ноль при развертывании необязательного значения для зашифрованной строки
3 ответа
Вы используете 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
}
Выход:
decryptedString: секрет
Заметки:
Не используйте CryptoSwift, он не использует встроенное аппаратное шифрование и в 400-1000 раз медленнее, чем Apple Security.framework Common Crypto. Он также недостаточно хорошо проверен и использует несертифицированный код шифрования.
Не используйте строку непосредственно в качестве ключа, это небезопасно. Вместо этого извлеките ключ из строки, используя PBKDK2 (функция получения ключа на основе пароля).
Строки Base64 должны делиться на 4. Ваша нет. Вы можете использовать веб-сайт, такой как https://www.base64decode.org/, для проверки своих строк.
Для 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
}