一. Mac上生成 ECDHE(Elliptic Curve Diffie-Hellman Ephemeral)公钥和私钥
1.Mac安装OpenSSL
2.生成 ECDHE 密钥对
1
|
openssl ecparam -name prime256v1 -genkey -noout -out private_key.pem
|
终端命令将生成一个 prime256v1(也称为 P-256)曲线的 ECDHE 私钥,并将私钥保存到 private_key.pem 文件中。
3.导出公钥
1
|
openssl ec -in private_key.pem -pubout -out public_key.pem
|
终端命令将从 private_key.pem 文件中导出公钥,并保存到 public_key.pem 文件
二.iOS中的使用
1.工程引入公钥和私钥文件
2.工程引入CryptoKit库
3.加载公钥和私钥
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
func loadKeyAndSecret() -> SymmetricKey? {
// 加载本地私钥文件
guard let privateKeyURL = Bundle.main.url(forResource: EcdheTest.PrivateKeyFile, withExtension: "pem"),
let privateKeyString = try? String(contentsOf: privateKeyURL) else {
fatalError("Failed to load private key")
}
// 解析本地私钥
let privateKey = try! P256.KeyAgreement.PrivateKey(pemRepresentation: privateKeyString)
// 加载对方的公钥文件
guard let publicKeyURL = Bundle.main.url(forResource: EcdheTest.PublicKeyFile, withExtension: "pem"),
let publicKeyString = try? String(contentsOf: publicKeyURL) else {
fatalError("Failed to load peer's public key")
}
// 解析对方的公钥
let peerPublicKey = try! P256.KeyAgreement.PublicKey(pemRepresentation: publicKeyString)
// 计算共享密钥
let sharedSecret = try! privateKey.sharedSecretFromKeyAgreement(with: peerPublicKey)
// 打印共享密钥
let sharedSecretData = sharedSecret.withUnsafeBytes { bytes in
return Data(bytes: bytes.baseAddress!, count: bytes.count)
}
// Print shared secret
print("Shared Secret: \(sharedSecretData)")
let hexString = sharedSecretData.map { String(format: "%02hhx", $0) }.joined()
// print("Hex String: \(hexString)")
// 使用共享的密钥进行加密/解密
return sharedSecret.hkdfDerivedSymmetricKey(using: SHA256.self, salt: Data(), sharedInfo: Data(), outputByteCount: 32)
}
|
4.数据加密
1
2
3
4
5
6
7
8
9
10
|
func encryptedData(_ symmetricKey: SymmetricKey, _ text: String) -> Data? {
guard let plaintext = text.data(using: .utf8) else {
return nil
}
return try? ChaChaPoly.seal(plaintext, using: symmetricKey).combined
}
|
5.数据解密
1
2
3
4
5
6
7
8
9
|
func decryptedData(_ symmetricKey: SymmetricKey, _ encryptedData: Data) -> Data? {
// 使用共享的密钥进行解密
guard let sealedBox = try? ChaChaPoly.SealedBox(combined: encryptedData) else {
return nil
}
return try? ChaChaPoly.open(sealedBox, using: symmetricKey)
}
|
6.测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
func test() {
let symmetricKey = self.loadKeyAndSecret()
guard symmetricKey != nil else {
fatalError("---loadKeyAndSecret load faile---")
}
let helloWorld = "Hello World!"
print("---helloWorld :\(helloWorld)")
let encryptedData = self.encryptedData(symmetricKey!, helloWorld)
guard encryptedData != nil else {
fatalError("---encryptedData faile---")
}
print("---encryptedData :\(String(describing: encryptedData))")
let decryptedData = self.decryptedData(symmetricKey!, encryptedData!)
guard decryptedData != nil else {
fatalError("---decryptedData faile---")
}
let decryptedString = String(data: decryptedData!, encoding: .utf8)
print("---decryptedData:\(decryptedString ?? "" )")
}
|
7.执行情况
1
2
3
4
|
Shared Secret: 32 bytes
---helloWorld :Hello World!
---encryptedData :Optional(40 bytes)
---decryptedData:Hello World!
|
文章作者
梵梵爸
上次更新
2023-09-20
许可协议
原创文章,如需转载请注明文章作者和出处。谢谢