
- (NSData *)AES256EncryptWithKey:(NSString *)key { NSUInteger dataLength = [self length]; size_t bufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize) NSMutableData *data = [[NSData randomDataWithLength:AES_256_IV_SIZE] mutableCopy]; //IV size_t numBytesEncrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, [key cStringUsingEncoding:NSUTF8StringEncoding], [key length], [data bytes], [self bytes], dataLength, buffer, bufferSize, &numBytesEncrypted); if (cryptStatus == kCCSuccess) { NSData *message = [NSData dataWithBytes:buffer length:numBytesEncrypted]; //Message /* Do HMac */ NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding]; NSData *hmac = [message doHmacWithKeyData:keyData]; /* IV+Message+HMac */ [data appendData:message]; [data appendData:hmac]; free(buffer); return data; } free(buffer); return nil; } - (NSData *)doHmacWithKeyData:(NSData *)salt { NSMutableData *macOut = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH]; CCHmac(kCCHmacAlgSHA256, salt.bytes, salt.length, self.bytes, self.length, macOut.mutableBytes); return macOut; } 1 finab 2020-08-27 16:50:39 +08:00 https://swiftify.com/converter/code/ 这个可以将 Objc 代码转成 Swift,可能会有一些错误,需要修改。 |
2 CommandZi 2020-08-27 17:23:58 +08:00 |
3 usVexMownCzar 2020-08-27 17:59:01 +08:00 @finab 这个不错,需要注意的地方,非登录情况下,支持 1K 以下的代码 |
4 chillwind OP 看了半天 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(hac) 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) } } ``` |
5 f165af34d4830eeb 2020-08-29 13:17:41 +08:00 via iPhone swift 的话,可以试试原生的 CryptoSwift 。https://github.com/krzyzanowskim/CryptoSwift |