当公钥和对称密钥一起工作时

有了椭圆曲线密码术(ECC),我们有机会同时使用公钥加密的强大功能,以及对称密钥加密的速度和安全性。因此,我们慢慢地转向加密的最佳实践,围绕以下方面达成越来越多的共识:
公钥加密曲线:P256、P384、P521、X25519、X448。
密钥派生推导的哈希法(HKDF):SHA256, SHA384和SHA512。
对称密钥:128位AES GCM和256位AES GCM。
以上所有方法都与大多数系统兼容。为此,Bob和Alice将选择一条曲线来定义他们的密钥对,然后使用给定的散列方法来派生一个加密密钥。这通常是通过HKDF (HMAC密钥推导功能)实现的。对于实际的加密,我们可以使用对称密钥加密,因为这是最有效的,比公钥加密快得多。总的来说,有了这种技术,就有了使用AEAD(附加数据验证加密)的一般趋势。典型的模式是GCM。因此,让我们用Golang构建一个混合加密方法。
Bob与Alice
现在,假设Bob将向Alice发送一条加密消息。然后Alice将生成一个密钥对(一个公钥和一个私钥)。然后她将她的公钥发送给Bob,然后Bob使用这个来获得用于加密(S)的对称密钥。然后他使用K和AES GCM来加密消息。Bob接收到密码(C)和一个R值。从R中,她可以从她的私钥中推导出S。有了这个密钥,她就可以解密密文,得到明文消息。
在这种方法中,Alice生成一个随机私钥(dA),在椭圆曲线(G)上取一个点,然后确定她的公钥(QA):
QA = dA×G
因此G和QA是椭圆曲线上的点。然后Alice将QA(她的公钥)发送给Bob。接下来,Bob将生成:
R = r × G
S = r × QA
其中r 是 Bob 生成的随机数。然后使用对称密钥(S)加密消息。然后Alice将和R一起收到加密消息,她可以确定相同的加密密钥:
S = dA×R
这是:
S = dA × (r×G)
S = r × (dA×G)
S = r×QA
和Bob生成的密钥相同。方法如下:

代码如下:
package mainimport ("crypto/rand""encoding/hex""fmt""os""strconv""github.com/cloudflare/circl/hpke")func main() {kemID := int(hpke.KEM_P256_HKDF_SHA256)kdfID := int(hpke.KDF_HKDF_SHA256)aeadID := int(hpke.AEAD_AES128GCM)msg := "Hello"argCount := len(os.Args[1:])if argCount > 0 {msg = os.Args[1]}if argCount > 1 {kemID, _ = strconv.Atoi(os.Args[2])}if argCount > 2 {kdfID, _ = strconv.Atoi(os.Args[3])}if argCount > 3 {aeadID, _ = strconv.Atoi(os.Args[4])}suite := hpke.NewSuite(hpke.KEM(kemID), hpke.KDF(kdfID), hpke.AEAD(aeadID))info := []byte("Test")Bob_pub, Bob_private, _ := hpke.KEM(kemID).Scheme().GenerateKeyPair()Bob, _ := suite.NewReceiver(Bob_private, info)Alice, _ := suite.NewSender(Bob_pub, info)enc, sealer, _ := Alice.Setup(rand.Reader)Alice_msg := []byte(msg)aad := []byte("Additional data")ct, _ := sealer.Seal(Alice_msg, aad)opener, _ := Bob.Setup(enc)Bob_msg, _ := opener.Open(ct, aad)fmt.Printf("Public key type:\t%s\n", Bob_pub.Scheme().Name())fmt.Printf(" Params\t%s\n", suite.String())fmt.Printf("Key exchange parameters:\n")fmt.Printf(" Ciphersize:\t%d\n", hpke.KEM(kemID).Scheme().CiphertextSize())fmt.Printf(" EncapsulationSeedSize:\t%d\n", hpke.KEM(kemID).Scheme().EncapsulationSeedSize())fmt.Printf(" PrivateKeySize:\t%d\n", hpke.KEM(kemID).Scheme().PrivateKeySize())fmt.Printf(" PublicKeySize:\t%d\n", hpke.KEM(kemID).Scheme().PublicKeySize())fmt.Printf(" SeedSize:\t%d\n", hpke.KEM(kemID).Scheme().SeedSize())fmt.Printf(" SharedKeySize:\t%d\n", hpke.KEM(kemID).Scheme().SharedKeySize())fmt.Printf("Cipher parameters:\n")fmt.Printf(" Key Length:\t%d\n", hpke.AEAD(aeadID).KeySize())fmt.Printf("Key derivation function:\n")fmt.Printf(" Extract size:\t%d\n", hpke.KDF(kdfID).ExtractSize())fmt.Printf("\nMessage:\t%s\n", Alice_msg)fmt.Printf("Cipher:\t%x\n", hex.EncodeToString(ct))fmt.Printf("Decipher:\t%s\n", Bob_msg)}
以及 P256 和 SHA-256 的示例运行:
Public key type: HPKE_KEM_P256_HKDF_SHA256Params kem_id: 16 kdf_id: 1 aead_id: 2Key exchange parameters:Ciphersize: 65EncapsulationSeedSize: 32PrivateKeySize: 32PublicKeySize: 65SeedSize: 32SharedKeySize: 32Cipher parameters:Key Length: 32Key derivation function:Extract size: 32Message: Testing 123Cipher: 353065393764366564633530623733346632376261653466376532663130343731353562323961633964373432666539656237616464Decipher: Testing 123
结论
我们有像OpenSSL这样的库,它们有大量的“包袱”。有了这个,对一系列方法的支持通常会引入错误和安全漏洞的机会。所以,去做混合:
https://asecuritysite.com/golang/go_hybrid
如果想了解更多关于ECIES的信息,试试这里:
https://asecuritysite.com/ecies
和CIRCL:
https://asecuritysite.com/circl
Source:https://medium.com/asecuritysite-when-bob-met-alice/when-public-key-and-symmetric-key-work-together-perfectly-650893c7d521
关于
ChinaDeFi - ChinaDeFi.com 是一个研究驱动的DeFi创新组织,同时我们也是区块链开发团队。每天从全球超过500个优质信息源的近900篇内容中,寻找思考更具深度、梳理更为系统的内容,以最快的速度同步到中国市场提供决策辅助材料。
Layer 2道友 - 欢迎对Layer 2感兴趣的区块链技术爱好者、研究分析人与Gavin(微信: chinadefi)联系,共同探讨Layer 2带来的落地机遇。敬请关注我们的微信公众号 “去中心化金融社区”。

【免责声明】市场有风险,投资需谨慎。本文不构成投资建议,用户应考虑本文中的任何意见、观点或结论是否符合其特定状况。据此投资,责任自负。
来源链接

