做dj网站能赚钱吗,wordpress秒开,南宁网站怎么制作公司,浙江和海建设集团网站首页感觉iOS自带的CryptoKit不好用#xff0c;有个第三方库CryptoSwift还不错#xff0c;好巧不巧#xff0c;清理过Xcode缓存后死活下载不下来#xff0c;当然也可以自己编译个Framework#xff0c;但是偏偏不想用第三方库了#xff0c;于是研究了一下#xff0c;自带的Com…感觉iOS自带的CryptoKit不好用有个第三方库CryptoSwift还不错好巧不巧清理过Xcode缓存后死活下载不下来当然也可以自己编译个Framework但是偏偏不想用第三方库了于是研究了一下自带的CommonCrypto也可以达到项目需求。
代码主要包含以下算法
AES128/CBC/NoPadding
AES128/CTR/NoPadding
AES-CMAC
import Foundation
import CommonCryptoclass AESUtil {private init(){}//////AES-CMAC///static func CMAC(key: Data, data: Data) - Data? {let blockSize 16var subKey1 Data(count: blockSize)var subKey2 Data(count: blockSize)// Step 1: Generate subkeysguard generateSubKeys(key: key, subKey1: subKey1, subKey2: subKey2) else {return nil}// Step 2: Calculate the number of blockslet blockCount (data.count blockSize - 1) / blockSize// Step 3: Process each blockvar lastBlock Data(count: blockSize)for i in 0..blockCount {let blockRange i * blockSize..min((i 1) * blockSize, data.count)var block data.subdata(in: blockRange)if i blockCount - 1 {if block.count blockSize {block.append(0x80)while block.count blockSize {block.append(0x00)}block xor(data: block, with: subKey2)} else {block xor(data: block, with: subKey1)}}lastBlock xor(data: lastBlock, with: block)lastBlock CBC(key: key, data: lastBlock, isEncrypt: true)!}return lastBlock}private static func generateSubKeys(key: Data, subKey1: inout Data, subKey2: inout Data) - Bool {let blockSize 16let zeroBlock Data(count: blockSize)guard let L CBC(key: key, data: zeroBlock, isEncrypt: true) else {return false}subKey1 generateSubKey(block: L)subKey2 generateSubKey(block: subKey1)return true}private static func generateSubKey(block: Data) - Data {let blockSize 16var subKey Data(count: 16)var overflow falsefor i in (0..blockSize).reversed() {let byte block[i]let shiftedByte byte 1subKey[i] shiftedByte | (overflow ? 1 : 0)overflow (byte 0x80) ! 0}if overflow {subKey[blockSize - 1] ^ 0x87}return subKey}private static func xor(data: Data, with other: Data) - Data {var result Data(count: data.count)for i in 0..data.count {result[i] data[i] ^ other[i]}return result}//////AES128/CBC/NoPadding加解密//////param isEncrypt true加密false解密///static func CBC(key: Data, data: Data, isEncrypt: Bool) - Data? {return AES128NoPadding(key: key, iv: Data(count: 16), data: data, mode: CBC, isEncrypt: isEncrypt)}//////AES128/CTR/NoPadding加解密//////param isEncrypt true加密false解密///static func CTR(key: Data, data: Data, isEncrypt: Bool) - Data? {return AES128NoPadding(key: key, iv: Data(count: 16), data: data, mode: CTR, isEncrypt: isEncrypt)}//////AES128/NoPadding加解密//////param mode 支持CBC、CTR///param isEncrypt true加密false解密///static func AES128NoPadding(key: Data, iv: Data, data: Data, mode: String, isEncrypt: Bool) - Data? {let bufferLength data.count kCCKeySizeAES128var buffer Data(count: bufferLength)var numBytesEncrypted: size_t 0let operation isEncrypt ? kCCEncrypt : kCCDecryptlet cryptStatus: CCCryptorStatus buffer.withUnsafeMutableBytes { (bufferPtr: UnsafeMutableRawBufferPointer) inkey.withUnsafeBytes { (keyPtr: UnsafeRawBufferPointer) iniv.withUnsafeBytes { (ivPtr: UnsafeRawBufferPointer) indata.withUnsafeBytes { (dataPtr: UnsafeRawBufferPointer) in//调用加密函数var modeSource 0if mode CBC {modeSource kCCModeCBC} else if mode CTR {modeSource kCCModeCTR}let cryptorRef UnsafeMutablePointerCCCryptorRef?.allocate(capacity: 1)var status CCCryptorCreateWithMode(CCOperation(operation), CCMode(modeSource), CCAlgorithm(kCCAlgorithmAES), CCPadding(ccNoPadding), ivPtr.baseAddress, keyPtr.baseAddress, kCCKeySizeAES128, nil, 0, 0, CCModeOptions(0), cryptorRef)if status kCCSuccess {status CCCryptorUpdate(cryptorRef.pointee, dataPtr.baseAddress, data.count, bufferPtr.baseAddress, bufferLength, numBytesEncrypted)} else {print(CCCryptorCreateWithMode fail: \(encryptError(status)))}return status}}}}if cryptStatus kCCSuccess {buffer.removeSubrange(numBytesEncrypted..bufferLength)return buffer}print(AES/\(mode)/NoPadding加解密失败: \(encryptError(cryptStatus)))return nil}private static func encryptError(_ status: CCCryptorStatus)- String {if status kCCParamError {return kCCParamError} else if status kCCBufferTooSmall {return kCCBufferTooSmall} else if status kCCMemoryFailure {return kCCMemoryFailure} else if status kCCAlignmentError {return kCCAlignmentError} else if status kCCDecodeError {return kCCDecodeError} else if status kCCUnimplemented {return kCCUnimplemented} else if status kCCOverflow {return kCCOverflow} else if status kCCRNGFailure {return kCCRNGFailure} else if status kCCUnspecifiedError {return kCCUnspecifiedError} else if status kCCCallSequenceError {return kCCCallSequenceError} else if status kCCKeySizeError {return kCCKeySizeError} else if status kCCInvalidKey {return kCCInvalidKey}return \(status)}
}