- (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
|
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(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) } } ``` |
5
f165af34d4830eeb 2020-08-29 13:17:41 +08:00 via iPhone
swift 的话,可以试试原生的 CryptoSwift 。https://github.com/krzyzanowskim/CryptoSwift
|