java ecdh秘钥交换,ECDH密钥协商算法

ECDH是EC是"elliptic curves"的意思,DH是"Diffie-Hellman"的意思。它实际上是密钥协商算法,而不是加解密算法。

该算法可以用来解决如下问题:

在公网通道上如何进行安全的秘钥分派。

两端(Alice 和 Bob)想要安全的交换信息并且第三方不能获取到该信息。当然这也是TLS协议中的目的之一,举个例子。(其实下面的描述其实是ECDHE,而不是ECDH)

Alice 和 Bob 生成他们自己的私钥和公钥,即Alice 有 da、Ha = da*G;Bob有db、Hb = db *G。

Alice把Ha发给Bob,Bob把Hb发给Alice。这样Alice 有da,Ha,Hb,Bob有db,Ha,Hb。

Alice计算S = daHb(即自己的私钥乘上Bob的公钥),同样的,Bob计算S = dbGa(自己的私钥乘上Alice的公钥)。两边计算的S是相同的。

S = da*Hb = da (db G) = db *(da *G) = db*Hb 等式1

中间人只知道到Ha和Hb,无法计算出共享密钥S。即离散对数问题为:中间人要计算 S,必须通过上述 等式1 中的一个等式来计算。显然必须知道da或者db,而中间人只知道Ha和Hb,即中间人为了获得da或者db需要从H或Hb中分离出da或db,显然这就是之前所说的离散对数问题。

现在Alice和Bob得到了共享密钥,后续可以使用共享密钥进行对称加密进行数据传输。通常情况下,点S中x向量被作为共享密钥。

例子

我们现在给出一个例子,设椭圆曲线为secp256k1(在SECG中被定义),它的

参数如下:

474635010c37ef51caeeb75a1b4f4bd6.png

Alice的私钥(随机数):

0xe32868331fa8ef0138de0de85478346aec5e3912b6029ae71691c384237a3eeb

Alice的公钥(由Alice的随机数乘上基点):

(0x86b1aa5120f079594348c67647679e7ac4c365b2c01330db782b0ba611c1d677, 0x5f4376a23eed633657a90f385ba21068ed7e29859a7fab09e953cc5b3e89beba)

Bob的私钥(随机数):

0xcef147652aa90162e1fff9cf07f2605ea05529ca215a04350a98ecc24aa34342

Bob的公钥(由Bob的随机数乘上基点):

(0x4034127647bb7fdab7f1526c7d10be8b28174e2bba35b06ffd8a26fc2c20134a, 0x9e773199edc1ea792b150270ea3317689286c9fe239dd5b9c5cfd9e81b4b632)

双方得到的共享密钥:

(0x3e2ffbc3aa8a2836c1689e55cd169ba638b58a3a18803fcf7de153525b28c3cd, 0x43ca148c92af58ebdb525542488a4fe6397809200fe8c61b41a105449507083)

总结:

粗暴的理解记忆是,Alice和Bob协商着把共享密钥算了出来。

另外,您也可以了解下区块链用的ECDSA签名算法

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是 Java 实现 ECDH 算法的示例代码: ```java import java.security.*; import java.security.spec.*; import javax.crypto.*; import javax.crypto.spec.*; public class ECDHDemo { public static void main(String[] args) throws Exception { // 创建椭圆曲线密钥对生成器 KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC"); // 使用 secp256r1 椭圆曲线 kpg.initialize(new ECGenParameterSpec("secp256r1")); // 生成密钥对 KeyPair kp1 = kpg.generateKeyPair(); KeyPair kp2 = kpg.generateKeyPair(); // 获取公钥和私钥 PublicKey pubKey1 = kp1.getPublic(); PrivateKey priKey1 = kp1.getPrivate(); PublicKey pubKey2 = kp2.getPublic(); PrivateKey priKey2 = kp2.getPrivate(); // ECDH 密钥协商 KeyAgreement ka1 = KeyAgreement.getInstance("ECDH"); ka1.init(priKey1); ka1.doPhase(pubKey2, true); byte[] secret1 = ka1.generateSecret(); KeyAgreement ka2 = KeyAgreement.getInstance("ECDH"); ka2.init(priKey2); ka2.doPhase(pubKey1, true); byte[] secret2 = ka2.generateSecret(); // 验证协商密钥是否相同 if (MessageDigest.isEqual(secret1, secret2)) { System.out.println("ECDH 密钥协商成功!"); } else { System.out.println("ECDH 密钥协商失败!"); } } } ``` 在上面的示例代码中,我们使用 `secp256r1` 椭圆曲线生成密钥对,并使用 ECDH 算法进行密钥协商。具体步骤如下: 1. 通过 `KeyPairGenerator` 生成密钥对。 2. 获取公钥和私钥。 3. 创建 `KeyAgreement` 实例,初始化为自己的私钥。 4. 使用 `doPhase` 方法将对方的公钥作为输入,并执行密钥协商。 5. 使用 `generateSecret` 方法生成协商密钥。 6. 验证双方协商密钥是否相同,如果相同则密钥协商成功。 值得注意的是,ECDH 密钥协商只能协商出一个共享密钥,而且这个共享密钥不是公钥或私钥,它只能用于对称加密。因此,在实际应用中,我们通常需要使用协商出的共享密钥来加密通信内容。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值