CryptoKit 实现 椭圆曲线ECC加密

1、有没有一种方式让两个人的对话绝对安全呢?答案是肯定有的 那就是使用 椭圆曲线ECC加密

2、椭圆曲线ECC加密原理 假设有两个用户A和B 、A随机生成一个密码对包含了公钥和私钥 同理B也随机生成一个密码对包含了公钥和私钥 

3、这个时候使用A的私钥和B的公钥生成一个共享秘钥、同理使用B的私钥和A的公钥生成一个共享秘钥、这两个秘钥值是相等的

4、那就就可以利用这一点对数据进行加密、公钥共享到服务器、私钥存储在用户本地、A向B发送消息使用共享秘钥进行加密、比如使用AES进行加密、这时候B收到消息使用B生成的共享秘钥使用AES进行解密、如果本地密钥修改了或者卸载了安装、之前的离线消息将无法查看、这样就保证了数据的绝对安全性

5、目前由椭圆曲线公钥求解私钥的最有效算法复杂度为O(\sqrt{p}),其中p是阶数n的最大素因子。当参数选的足够好让p>2^{160}时,以目前的计算能力,攻破椭圆曲线是不现实的

import CryptoKit
import UIKit
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // 构造一个salt,生成密钥时需要使用
        let salt = "YungFan".data(using: .utf8)!

        // 用户A和用户B都会生成一对公钥和私钥
        let privateKeyA = P521.KeyAgreement.PrivateKey()
        let publicKeyA = privateKeyA.publicKey

        let privateKeyB = P521.KeyAgreement.PrivateKey()
        let publicKeyB = privateKeyB.publicKey

        // 用户A用私钥和用户B的公钥产生一个共享的密钥
        let sharedSecretA = try? privateKeyA.sharedSecretFromKeyAgreement(with: publicKeyB)
        let symmetricKeyA = sharedSecretA?.hkdfDerivedSymmetricKey(using: SHA256.self, salt: salt, sharedInfo: Data(), outputByteCount: 32)

        // 用户B用私钥和用户A的公钥产生一个共享的密钥
        let sharedSecretB = try? privateKeyB.sharedSecretFromKeyAgreement(with: publicKeyA)
        let symmetricKeyB = sharedSecretB?.hkdfDerivedSymmetricKey(using: SHA256.self, salt: salt, sharedInfo: Data(), outputByteCount: 32)

        if symmetricKeyA == symmetricKeyB {
            print("A和B经过协商产生了共享密钥")
        }
        cryptoDemoCombinedData(key: symmetricKeyA!)
    }

    func cryptoDemoCombinedData(key: SymmetricKey) {
        let nonce = try! AES.GCM.Nonce(data: Data(base64Encoded: "fv1nixTVoYpSvpdA")!)
        let tag = Data(base64Encoded: "e1eIgoB4+lA/j3KDHhY4BQ==")!

        // Encrypt
        let sealedBox = try! AES.GCM.seal("123".data(using: .utf8)!, using: key, nonce: nonce, authenticating: tag)

        // Decrypt
        let sealedBoxRestored = try! AES.GCM.SealedBox(combined: sealedBox.combined!)
        let decrypted = try! AES.GCM.open(sealedBoxRestored, using: key, authenticating: tag)

        print("Crypto Demo II\n••••••••••••••••••••••••••••••••••••••••••••••••••\n")
        print("Combined:\n\(sealedBox.combined!.base64EncodedString())\n")
        print("Cipher:\n\(sealedBox.ciphertext.base64EncodedString())\n")
        print("Nonce:\n\(nonce.withUnsafeBytes { Data(Array($0)).base64EncodedString() })\n")
        print("Tag:\n\(tag.base64EncodedString())\n")
        print("Decrypted:\n\(String(data: decrypted, encoding: .utf8)!)\n")
    }
}

 

posted @ 2022-02-25 10:46  ZhangShengjie  阅读(459)  评论(0编辑  收藏  举报