V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
chillwind
V2EX  ›  macOS

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

  •  
  •   chillwind · 2020-08-27 16:47:34 +08:00 · 1982 次点击
    这是一个创建于 1540 天前的主题,其中的信息可能已经有所发展或是发生改变。
    - (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;
    }
    
    5 条回复    2020-08-29 13:17:41 +08:00
    finab
        1
    finab  
       2020-08-27 16:50:39 +08:00
    https://swiftify.com/converter/code/
    这个可以将 Objc 代码转成 Swift,可能会有一些错误,需要修改。
    chiaf
        3
    chiaf  
       2020-08-27 17:59:01 +08:00
    @finab 这个不错,需要注意的地方,非登录情况下,支持 1K 以下的代码
    chillwind
        4
    chillwind  
    OP
       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
        5
    f165af34d4830eeb  
       2020-08-29 13:17:41 +08:00 via iPhone
    swift 的话,可以试试原生的 CryptoSwift 。https://github.com/krzyzanowskim/CryptoSwift
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1044 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 21:16 · PVG 05:16 · LAX 13:16 · JFK 16:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.