美文网首页
CryptoKit简易使用教程

CryptoKit简易使用教程

作者: LonnieQ | 来源:发表于2021-01-05 20:56 被阅读0次

    哈希数据

    支持的哈希算法有

    • MD5
    • SHA1
    • SHA256
    • SHA384
    • SHA512

    其中MD5、SHA1被认为是不安全的哈希算法。

    import CryptoKit
    let data = "Hello world".data(using: .utf8)!
    var sha256 = SHA256()
    sha256.update(data: data)
    print(sha256.finalize())
    // SHA256 digest: 64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c
    

    HMAC验证数据

    import CryptoKit
    let data = "Hello world".data(using: .utf8)!
    let key = SymmetricKey(data: Array(0..<32))
    // 生成数据验证码
    let authenticateCode = HMAC<SHA256>.authenticationCode(for: data, using: key)
    print(authenticateCode)
    // HMAC with SHA256: 8d02cc6dde5f1711bef21a1ed4b2d52f0c39daa8cef255bccae53ca24ef2f180
    let authenticateCodeData = Data(authenticateCode)
    // 验证数据
    let isValid = HMAC<SHA256>.isValidAuthenticationCode(authenticateCodeData, authenticating: data, using: key)
    print(isValid)
    // true
    

    对称加密

    该框架支持的对称加密算法有限:

    • GCM模式的AES算法
    • ChaChaPoly
    import CryptoKit
    let data = "Hello world".data(using: .utf8)!
    let key = SymmetricKey(data: Array(0..<32))
    // 加密数据
    let encrypted = try AES.GCM.seal(data, using: key).combined!
    // 解密数据
    let box = try AES.GCM.SealedBox(combined: encrypted)
    let decrypted = try AES.GCM.open(box, using: key)
    print(String(data: decrypted, encoding: .utf8)!)
    // Hello world
    

    利用Key Agreement交换密钥

    import CryptoKit
    let salt = "Salt".data(using: .utf8)!
    // 为Alice生成密钥对
    let alicePrivateKey = P256.KeyAgreement.PrivateKey()
    let alicePublicKey = alicePrivateKey.publicKey
    // 为Bob生成密钥对
    let bobPrivateKey = P256.KeyAgreement.PrivateKey()
    let bobPublicKey = bobPrivateKey.publicKey
    // 使用Alice的私钥和Bob的公钥计算出Alice的对称密钥
    let aliceSharedSecret = try! alicePrivateKey.sharedSecretFromKeyAgreement(with: bobPublicKey)
    let aliceSymmetricKey = aliceSharedSecret.hkdfDerivedSymmetricKey(
        using: SHA256.self,
        salt: salt,
        sharedInfo: Data(),
        outputByteCount: 32
    )
    // 使用Bob的私钥和Alice的公钥计算出Bob的对称密钥
    let bobSharedSecret = try! bobPrivateKey.sharedSecretFromKeyAgreement(with: alicePublicKey)
    let bobSymmetricKey = bobSharedSecret.hkdfDerivedSymmetricKey(
        using: SHA256.self,
        salt: salt,
        sharedInfo: Data(),
        outputByteCount: 32
    )
    // Alice和Bob拥有相同的对称密钥
    print(aliceSymmetricKey == bobSymmetricKey)
    // true
    

    创建和验证签名

    import CryptoKit
    let data = "Hello world".data(using: .utf8)!
    // 生成密钥对
    let signingKey = Curve25519.Signing.PrivateKey()
    let signingPublicKey = signingKey.publicKey
    let signingPublicKeyData = signingPublicKey.rawRepresentation
    let initializedSigningPublicKey = try! Curve25519.Signing.PublicKey(rawRepresentation: signingPublicKeyData)
    // 使用私钥计算签名
    let signautre = try! signingKey.signature(for: data)
    // 使用公钥验证签名
    print(initializedSigningPublicKey.isValidSignature(signautre, for: data))
    // true
    

    公钥加密

    enum DecryptionErrors: Error {
        case authenticationError
    }
    let salt = "Salt".data(using: .utf8)!
    
    func encrypt(_ data: Data, to theirEncryptionKey: Curve25519.KeyAgreement.PublicKey, signedBy ourSigningKey: Curve25519.Signing.PrivateKey) throws ->
        (ephemeralPublicKeyData: Data, ciphertext: Data, signature: Data) {
            // 创建临时密钥对
            let ephemeralKey = Curve25519.KeyAgreement.PrivateKey()
            let ephemeralPublicKey = ephemeralKey.publicKey.rawRepresentation
            
            // 计算对称密钥
            let sharedSecret = try ephemeralKey.sharedSecretFromKeyAgreement(
                with: theirEncryptionKey
            )
            
            let symmetricKey = sharedSecret.hkdfDerivedSymmetricKey(
                using: SHA256.self,
                salt: salt,
                sharedInfo: ephemeralPublicKey + theirEncryptionKey.rawRepresentation + ourSigningKey.publicKey.rawRepresentation,
                outputByteCount: 32
            )
            // 利用对称密钥生成秘文
            let ciphertext = try ChaChaPoly.seal(data, using: symmetricKey).combined
        
            // 计算签名
            let signature = try ourSigningKey.signature(for: ciphertext + ephemeralPublicKey + theirEncryptionKey.rawRepresentation)
            //返回随机生成的公钥、秘文及签名
            return (ephemeralPublicKey, ciphertext, signature)
    }
    
    func decrypt(_ sealedMessage: (ephemeralPublicKeyData: Data, ciphertext: Data, signature: Data),
                 using ourKeyEncryptionKey: Curve25519.KeyAgreement.PrivateKey,
                 from theirSigningKey: Curve25519.Signing.PublicKey) throws -> Data {
        // 验证签名
        let data = sealedMessage.ciphertext + sealedMessage.ephemeralPublicKeyData + ourKeyEncryptionKey.publicKey.rawRepresentation
        guard theirSigningKey.isValidSignature(sealedMessage.signature, for: data) else {
            throw DecryptionErrors.authenticationError
        }
    
        let ephemeralKey = try Curve25519.KeyAgreement.PublicKey(
            rawRepresentation: sealedMessage.ephemeralPublicKeyData
        )
        
        // 计算对称密钥
        let sharedSecret = try ourKeyEncryptionKey.sharedSecretFromKeyAgreement(
            with: ephemeralKey
        )
        
        let symmetricKey = sharedSecret.hkdfDerivedSymmetricKey(
            using: SHA256.self,
            salt: salt,
            sharedInfo: ephemeralKey.rawRepresentation + ourKeyEncryptionKey.publicKey.rawRepresentation +
                                                                    theirSigningKey.rawRepresentation,
            outputByteCount: 32
        )
        
        // 利用对称密钥解密数据
        let sealedBox = try ChaChaPoly.SealedBox(combined: sealedMessage.ciphertext)
        
        return try ChaChaPoly.open(sealedBox, using: symmetricKey)
    }
    
    let data = "Hello world".data(using: .utf8)!
    // 创建发送者的签名密钥
    let senderSigningKey = Curve25519.Signing.PrivateKey()
    let senderSigningPublicKey = senderSigningKey.publicKey
    // 创建接收者的加密密钥
    let receiverEncryptionKey = Curve25519.KeyAgreement.PrivateKey()
    let receiverEncryptionPublicKey = receiverEncryptionKey.publicKey
    // 发送者利用接收者的公钥来加密数据,并使用发送者的私钥签名
    let encrypted = try encrypt(data, to: receiverEncryptionPublicKey, signedBy: senderSigningKey)
    
    // 接受者使用私钥加密数据,并使用发送者的公钥验证签名
    let decryptedMessage = try decrypt(encrypted, using: receiverEncryptionKey, from: senderSigningPublicKey)
    print("\(String(data: decryptedMessage, encoding: .utf8)!)")
    // Hello world
    

    相关文章

      网友评论

          本文标题:CryptoKit简易使用教程

          本文链接:https://www.haomeiwen.com/subject/ztzwoktx.html