 |
|
4
chillwind Aug 28, 2020
看了半天 swift,自己人肉转了一个。用的不对的地方,还请各位指正 ``` import Foundation import CommonCrypto
struct AES {
// MARK: - Value // MARK: Private private let key: Data // MARK: - Initialzier init?(key: String) { guard key.count == kCCKeySizeAES128 || key.count == kCCKeySizeAES256, let keyData = key.data(using: .utf8) else { debugPrint("Error: Failed to set a key.") return nil }
self.key = keyData }
// MARK: - Function // MARK: Public func encrypt(string: String) -> Data? { let iv = randomGenerateBytes(count: 16)! let cryptData = crypt(data: string.data(using: .utf8), iv: iv, option: CCOperation(kCCEncrypt))! var hmac = Data(count: 32) cryptData.withUnsafeBytes { v in hmac.withUnsafeMutableBytes { res in key.withUnsafeBytes { k in CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA256), k.baseAddress!, key.count, v.baseAddress!, cryptData.count, res.baseAddress!) } } } let messageData = NSMutableData() messageData.append(iv) messageData.append(cryptData) messageData.append(hmac) return messageData as Data }
func decrypt(data: Data) -> String? { //验证数据 let ivByteData = data.subdata(in: 0..<16)
let contentByteData = data.subdata(in: 16..<(data.count - 32)) let serverHmacData = data.subdata(in: (data.count - 32)..<data.count) print(data.count) var hmac = Data(count: 32) contentByteData.withUnsafeBytes { v in hmac.withUnsafeMutableBytes { res in key.withUnsafeBytes { k in CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA256), k.baseAddress!, key.count, v.baseAddress!, contentByteData.count, res.baseAddress!) } } } if (serverHmacData == hmac) { let decryptedData = crypt(data: contentByteData, iv: ivByteData, option: CCOperation(kCCDecrypt)) return String(bytes: decryptedData!, encoding: .utf8) } else { print("HMac 不一致") return nil; } }
func crypt(data: Data?, iv: Data, option: CCOperation) -> Data? { guard let data = data else { return nil }
let cryptLength = data.count + kCCBlockSizeAES128*2 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(kCCAlgorithmAES128), 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 }
func randomGenerateBytes(count: Int) -> Data? { let bytes = UnsafeMutableRawPointer.allocate(byteCount: count, alignment: 1) defer { bytes.deallocate() } let status = CCRandomGenerateBytes(bytes, count) guard status == kCCSuccess else { return nil } return Data(bytes: bytes, count: count) } }
```
|