一段 object c 代码想转 Swift ,有什么方法吗?

2020-08-27 16:47:34 +08:00
 chillwind
- (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;
}
1814 次点击
所在节点    macOS
5 条回复
finab
2020-08-27 16:50:39 +08:00
https://swiftify.com/converter/code/
这个可以将 Objc 代码转成 Swift,可能会有一些错误,需要修改。
CommandZi
2020-08-27 17:23:58 +08:00
chiaf
2020-08-27 17:59:01 +08:00
@finab 这个不错,需要注意的地方,非登录情况下,支持 1K 以下的代码
chillwind
2020-08-28 15:16:06 +08:00
看了半天 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)
}
}

```
f165af34d4830eeb
2020-08-29 13:17:41 +08:00
swift 的话,可以试试原生的 CryptoSwift 。https://github.com/krzyzanowskim/CryptoSwift

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/701952

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX