在python和swift之间交换加密消息



我需要一个python代码和一个swift代码交换加密消息。

这是我尝试的:

  1. Fernet

在审查了这些选项后,我认为对称密钥算法可以很好地工作。

在python中(像往常一样),加密和解密是很简单的:

Fernet(key).encrypt(b"mdg") # encrypt
Fernet(key).decrypt(encryptedMsg) # decrypt

在swift中,它最初看起来很简单,像这样:

func encrypt(key: String, msg: String) throws -> String {
let data = Data(base64URL: key)!
let symetricKey = try! SymmetricKey(data: d)
let msgUtf8 = msg.data(using: .utf8)!
let sealBox = try! AES.GCM.seal(msgUtf8, using: symetricKey, nonce: nil)
return sealBox.combined.base64EncodedString();
}

然而,我一直无法在swift中找到匹配python的Fernet的算法。

  • ChaCha
  • 在寻找这个问题的时候,我从Bram那里得到了这个惊人的答案。非常不幸的是,它只解决了我问题的一面:在python中加密消息并在swift中解码它们。我还需要反向处理。

    如何解决这个问题?

    首先,我们需要一种方法来创建安全的随机值来生成IV和密钥。您还可以使用CryptoKit的SymmetricKey生成密钥并从中提取数据,但现在,我将使用此函数。

    extension Data {
    static func secureRandom(ofSize size: Int) -> Data {
    var output = [UInt8](repeating: 0, count: size)
    _ = SecRandomCopyBytes(kSecRandomDefault, size, &output)
    return Data(output)
    }
    }
    

    然后我们需要计算AES CBC密文的可能性,这可以使用CommonCrypto完成。

    func encrypt(plaintext: Data, key: Data, iv: Data) -> Data {
    var encryptor: CCCryptorRef?
    defer {
    CCCryptorRelease(encryptor)
    }
    var key = Array(key)
    var iv = Array(iv)
    var plaintext = Array(plaintext)
    CCCryptorCreate(CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmAES), CCOperation(kCCOptionPKCS7Padding), &key, key.count, &iv, &encryptor)
    var outputBytes = [UInt8](repeating: 0, count: CCCryptorGetOutputLength(encryptor, plaintext.count, false))
    CCCryptorUpdate(encryptor, &plaintext, plaintext.count, &outputBytes, outputBytes.count, nil)
    var movedBytes = 0
    var finalBytes = [UInt8](repeating: 0, count: CCCryptorGetOutputLength(encryptor, 0, true))
    CCCryptorFinal(encryptor, &finalBytes, finalBytes.count, &movedBytes)
    return Data(outputBytes + finalBytes[0 ..< movedBytes])
    }
    

    和带有SHA-256哈希函数的HMAC。我建议在这里使用CryptoKit的HMAC实现,但为了保持简单,我使用了CommonCrypto实现。

    func computeHMAC(_ data: Data, using key: Data) -> Data {
    var data = Array(data)
    var key = Array(key)
    var macOut = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
    CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA256), &key, key.count, &data, data.count, &macOut)
    return Data(macOut)
    }
    

    这将所有这些组合到下面的

    let plaintext = Data("Hello world!".utf8)
    let signingKey = Data.secureRandom(ofSize: kCCKeySizeAES128)
    let cryptoKey = Data.secureRandom(ofSize: kCCKeySizeAES128)
    let fernetKey = (signingKey + cryptoKey).base64EncodedString()
    let version: [UInt8] = [0x80]
    let timestamp: [UInt8] = {
    let timestamp = Int(Date().timeIntervalSince1970).bigEndian
    return withUnsafeBytes(of: timestamp, Array.init)
    }()
    let iv = Data.secureRandom(ofSize: kCCBlockSizeAES128)
    let ciphertext = encrypt(plaintext: plaintext, key: cryptoKey, iv: iv)
    let hmac = computeHMAC(version + timestamp + iv + ciphertext, using: signingKey)
    let fernetToken = (version + timestamp + iv + ciphertext + hmac).base64EncodedString()
    print("Fernet key: (fernetKey)")
    print("Fernet token: (fernetToken)")
    

    输出示例可以是

    Fernet key: 7EwFlYNKTGfj+2fSgL3AUqtrRqRs4D1TWNK7t2XbGJQ=
    Fernet token: gAAAAABivCLM0y0poDtGOohT1yK4XTDJppYPJdu4fuDTZ5tb9P9KP5ACgX8aJq4imsSdbzOCcvY3Tueo4FYbwyG+ZugozILL+Q==
    

    可以在python中使用密码学。io的实现

    from cryptography.fernet import Fernet
    key = b'7EwFlYNKTGfj+2fSgL3AUqtrRqRs4D1TWNK7t2XbGJQ='
    token = b'gAAAAABivCLM0y0poDtGOohT1yK4XTDJppYPJdu4fuDTZ5tb9P9KP5ACgX8aJq4imsSdbzOCcvY3Tueo4FYbwyG+ZugozILL+Q=='
    Fernet(key).decrypt(token)
    # b'Hello world!'
    

    相关内容

    • 没有找到相关文章

    最新更新