ECDH 算法

一、简介

ECDH全称是椭圆曲线迪菲-赫尔曼秘钥交换(Elliptic Curve Diffie–Hellman key Exchange),主要是用来在一个不安全的通道中建立起安全的共有加密资料,一般来说交换的都是私钥,这个密钥一般作为“对称加密”的密钥而被双方在后续数据传输中使用。

ECDH是建立在这样一个前提之上的,给定椭圆曲线上的一个点P,一个整数k,求Q=KP很容易;但是通过Q,P求解K很难。

二、DH密钥交换原理

网上一个经典的场景,Alice和Bob要在一条不安全的线路上交换秘钥,交换的秘钥不能被中间人知晓。
首先,双方约定使用ECDH秘钥交换算法,这个时候双方也知道了ECDH算法里的一个大素数P,这个P可以看做是一个算法中的常量。

P的位数决定了攻击者破解的难度

还有一个整数g用来辅助整个秘钥交换,g不用很大,一般是2或者5,双方知道g和p之后就开始了ECDH交换秘钥的过程了。

Alice知道了共用参数p和g,生成私有整数a作为私钥,公钥算法一般是公钥加密,私钥解密,公钥给对方来加密数据,拿到密文后私钥解密查看内容正确性,这个时候Alice直接通过线路告诉Bob自己的私钥a显然既不合理也是一件风险很大的事。 这个时候Alice需要利用p,g,a通过公式 g a m o d p = A g^a mod p = A gamodp=A生成A作为公钥传递。

Bob通过链路收到Alice发来的p,g,A,知道了Alice的公钥A。这个时候Bob也生成自己的私钥b,然后通过公式 g b m o d p = B g^b mod p = B gbmodp=B生成自己公钥B。 在发送公钥B前,Bob通过 A b m o d p = K A^b mod p = K Abmodp=K生成K作为公共秘钥,但是并不发送给Alice,只通过链路发送B。

Alice收到Bob发来的公钥B以后,同样通过 B a m o d p = K B^a mod p = K Bamodp=K生成公共秘钥K,这样Alice和Bob就通过不传递私钥a和b完成了对公共秘钥K的协商。

请添加图片描述

三、说明示例

  1. Alice和Bob同意使用质数p和整数g:

p = 83 , g = 8 p = 83, g = 8 p=83,g=8

  1. Alice选择秘钥 a = 9 a = 9 a=9, 生成公钥 g a m o d p = A g^a mod p = A gamodp=A 并发送

( 8 9 ) m o d 83 = 5 (8^9) mod 83 = 5 (89)mod83=5

  1. Bob选择秘钥 b = 21 b = 21 b=21, 生成公钥 $g^b mod p = B $并发送

( 8 2 1 ) m o d 83 = 18 (8^21) mod 83 = 18 (821)mod83=18

  1. Alice计算 B a m o d p = K B^a mod p = K Bamodp=K

1 8 9 m o d 83 = 24 18^9 mod 83 = 24 189mod83=24

  1. Bob计算 B a m o d p = K B^a mod p = K Bamodp=K

5 2 1 m o d 83 = 24 5^21 mod 83 = 24 521mod83=24

至此24就是双方协商出来的秘钥。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值