刚毅的斑马 · Winform实战 | ...· 7 月前 · |
酒量大的足球 · Python基础学习之奇异的GUI对话框_p ...· 1 年前 · |
大方的椅子 · HDLBits练习汇总-03-Verilog ...· 1 年前 · |
爱喝酒的皮带 · JavaBean toString() - ...· 1 年前 · |
英俊的铁板烧 · sas proc sql trim ...· 1 年前 · |
我正在尝试在swift中实现AES加密。Android和C#的加密解密工作正常。我需要快速实现它。这是适用于安卓的 current code ,C#后面紧跟着这个。
我试着用
但这些都不管用。当我在服务器上发送加密的字符串时,它还没有被解密。
任何帮助我们都将不胜感激。
我的两点意见:
数据的swift 4/ xcode 9扩展:
extension Data{
func aesEncrypt( keyData: Data, ivData: Data, operation: Int) -> Data {
let dataLength = self.count
let cryptLength = size_t(dataLength + kCCBlockSizeAES128)
var cryptData = Data(count:cryptLength)
let keyLength = size_t(kCCKeySizeAES128)
let options = CCOptions(kCCOptionPKCS7Padding)
var numBytesEncrypted :size_t = 0
let cryptStatus = cryptData.withUnsafeMutableBytes {cryptBytes in
self.withUnsafeBytes {dataBytes in
ivData.withUnsafeBytes {ivBytes in
keyData.withUnsafeBytes {keyBytes in
CCCrypt(CCOperation(operation),
CCAlgorithm(kCCAlgorithmAES),
options,
keyBytes, keyLength,
ivBytes,
dataBytes, dataLength,
cryptBytes, cryptLength,
&numBytesEncrypted)
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
cryptData.removeSubrange(numBytesEncrypted..<cryptData.count)
} else {
print("Error: \(cryptStatus)")
return cryptData;
let message = "secret message"
let key = "key890123456"
let ivString = "abcdefghijklmnop" // 16 bytes for AES128
let messageData = message.data(using:String.Encoding.utf8)!
let keyData = key.data(using: .utf8)!
let ivData = ivString.data(using: .utf8)!
let encryptedData = messageData.aesEncrypt( keyData:keyData, ivData:ivData, operation:kCCEncrypt)
let decryptedData = encryptedData.aesEncrypt( keyData:keyData, ivData:ivData, operation:kCCDecrypt)
let decrypted = String(bytes:decryptedData, encoding:String.Encoding.utf8)!
return message == decrypted
}
找到了一个很好的库,叫做,用swift语言实现,用于AES加密/解密。
可以使用Cocoapods或Carthage进行安装。以下是加密和解密的示例代码。
// Encryption
let data = "sample data string".data(using: String.Encoding.utf8)
let password = "Secret password"
let encryptedData = RNCryptor.encrypt(data: data, withPassword: password)
// Decryption
let originalData = try RNCryptor.decrypt(data: encryptedData, withPassword: password)
// ...
} catch {
print(error)
}
我用过CryptoSwift。
首先,我在pod文件中安装了cryptoSwift。然后在我的视图控制器中,我导入了CryptoSwift。
下面是我使用的代码:
let value = "xyzzy". // This is the value that we want to encrypt
let key = "abc". // This is the key
let EncryptedValue = try! value.aesEncrypt(key: key)
let DecryptedValue = try! EncryptedValue.aesDecrypt(key: key)
然后,使用字符串扩展:
extension String {
func aesEncrypt(key: String) throws -> String {
var result = ""
let key: [UInt8] = Array(key.utf8) as [UInt8]
let aes = try! AES(key: key, blockMode: .ECB, padding: .pkcs5) // AES128 .ECB pkcs7
let encrypted = try aes.encrypt(Array(self.utf8))
result = encrypted.toBase64()!
print("AES Encryption Result: \(result)")
} catch {
print("Error: \(error)")
return result
func aesDecrypt(key: String) throws -> String {
var result = ""
let encrypted = self
let key: [UInt8] = Array(key.utf8) as [UInt8]
let aes = try! AES(key: key, blockMode: .ECB, padding: .pkcs5) // AES128 .ECB pkcs7
let decrypted = try aes.decrypt(Array(base64: encrypted))
result = String(data: Data(decrypted), encoding: .utf8) ?? ""
print("AES Decryption Result: \(result)")
} catch {
print("Error: \(error)")
return result
}
在本文中,我没有使用iv和encrypted.toBase64()进行加密,比如在加密中使用
result = encrypted.toBase64()!
代替
result = encrypted.toStringHex()!
并且在代替
let decrypted = try aes.decrypt(Array(Hex: encrypted))
的解密
let decrypted = try aes.decrypt(Array(base64: encrypted))
上类似
对于不能将字节数组转换为字符串的任何人
String(data: Data(decrypted), encoding: .utf8)
这是我的字符串扩展示例
extension String {
func decryptAES(key: String, iv: String) -> String {
let encrypted = self
let key = Array(key.utf8)
let iv = Array(iv.utf8)
let aes = try AES(key: key, blockMode: CTR(iv: iv), padding: .noPadding)
let decrypted = try aes.decrypt(Array(hex: encrypted))
return String(data: Data(decrypted), encoding: .utf8) ?? ""
} catch {
return "Error: \(error)"
}
Swift 5
我重构了@ingconti的代码。
import Foundation
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 = data.count + kCCBlockSizeAES128
var cryptData = Data(count: cryptLength)
let keyLength = key.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.baseAddress, keyLength, ivBytes.baseAddress, dataBytes.baseAddress, data.count, cryptBytes.baseAddress, 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
}
像这样使用
let password = "UserPassword1!"
let key128 = "1234567890123456" // 16 bytes for AES128
let key256 = "12345678901234561234567890123456" // 32 bytes for AES256
let iv = "abcdefghijklmnop" // 16 bytes for AES128
let aes128 = AES(key: key128, iv: iv)
let aes256 = AES(key: key256, iv: iv)
let encryptedPassword128 = aes128?.encrypt(string: password)
aes128?.decrypt(data: encryptedPassword128)
let encryptedPassword256 = aes256?.encrypt(string: password)
aes256?.decrypt(data: encryptedPassword256)
结果
我知道这是一个老问题。
从2019年开始,你可以使用苹果的
CryptoKit
。它引入了
AES.GCM
import CryptoKit
let key = SymmetricKey(size: .bits256)
let data = Data(...)
let enc = try AES.GCM.seal(data, using: key).combined!
let dec = try AES.GCM.open(try AES.GCM.SealedBox(combined: data), using: key))
} catch {...}
此外,我还制作了一个有用的swift包,其中包含允许
AES.CBC
加密(
https://github.com/gal-yedidovich/CryptoExtensions
)的CryptoKit扩展
然后,只使用
import CBC
import CryptoKit
import CBC
let data: Data = ... //some data to encrypt
let iv: Data = ... //an initial vector
let key: SymmetricKey = ... //encryption key
//one shot crypto operation
let encrypted = try AES.CBC.encrypt(data, using: key, iv: iv)
let decrypted = try AES.CBC.decrypt(encrypted, using: key, iv: iv)
} catch {...}
//using cipher
let cipher = try AES.CBC.Cipher(.encrypt, using: key, iv: iv)
var enc = Data()
enc += try cipher.update(...)
enc += try cipher.update(...)
enc += try cipher.finalize()
} catch {...}
我正在寻找AES加密与PKC5填充ECB模式,而不使用任何豆荚。通过收集不同的信息,我找到了解决问题的合适方法。也许它可以对其他人有所帮助。
注意: PKCS5和PKCS7填充没有区别。
import CommonCrypto
func encryptionAESModeECB(messageData data: Data, key: String) -> Data? {
guard let keyData = key.data(using: String.Encoding.utf8) else { return nil }
guard let cryptData = NSMutableData(length: Int((data.count)) + kCCBlockSizeAES128) else { return nil }
let keyLength = size_t(kCCKeySizeAES128)
let operation: CCOperation = UInt32(kCCEncrypt)
let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES)
let options: CCOptions = UInt32(kCCOptionECBMode + kCCOptionPKCS7Padding)
let iv: String = ""
var numBytesEncrypted: size_t = 0
let cryptStatus = CCCrypt(operation,
algoritm,
options,
(keyData as NSData).bytes, keyLength,
(data as NSData).bytes, data.count,
cryptData.mutableBytes, cryptData.length,
&numBytesEncrypted)
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
cryptData.length = Int(numBytesEncrypted)
let encryptedString = cryptData.base64EncodedString(options: .lineLength64Characters)
return encryptedString.data(using: .utf8)
} else {
return nil
func decryptionAESModeECB(messageData: Data, key: String) -> Data? {
guard let messageString = String(data: messageData, encoding: .utf8) else { return nil }
guard let data = Data(base64Encoded: messageString, options: .ignoreUnknownCharacters) else { return nil }
guard let keyData = key.data(using: String.Encoding.utf8) else { return nil }
guard let cryptData = NSMutableData(length: Int((data.count)) + kCCBlockSizeAES128) else { return nil }
let keyLength = size_t(kCCKeySizeAES128)
let operation: CCOperation = UInt32(kCCDecrypt)
let algoritm: CCAlgorithm = UInt32(kCCAlgorithmAES)
let options: CCOptions = UInt32(kCCOptionECBMode + kCCOptionPKCS7Padding)
let iv: String = ""
var numBytesEncrypted: size_t = 0
let cryptStatus = CCCrypt(operation,
algoritm,
options,
(keyData as NSData).bytes, keyLength,
(data as NSData).bytes, data.count,
cryptData.mutableBytes, cryptData.length,
&numBytesEncrypted)
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
cryptData.length = Int(numBytesEncrypted)
return cryptData as Data