Diffie-Hellman密钥交换协议demo

背景

该协议基于离散对数问题的困难性来实现密钥交换,涉及到一些公开的参数和双方各自的秘密参数。通常假设有两个通信参与者,分别记为 Alice 和 Bob,他们要在不安全的网络环境下协商出一个共享的密钥,且整个过程中第三方很难通过截获的信息推算出这个密钥。

步骤

  1. 选择公开参数:
    首先,通信双方(Alice和Bob)共同选择一个大素数p以及p的一个本原根g,这两个参数p和g是公开的,任何参与通信或者潜在的窃听者都可以知道这两个值,它们可以通过事先约定或者在公开渠道进行公布等方式确定下来。
  2. 生成各自的秘密参数:
    Alice选择一个秘密的整数a,且0<a<p-1;Bob选择一个个秘密的整数b,同样满足0<b<p-1。这里的a和b是各自严格保密的,只有Alice知道a,只有Bcb 知道b。
  3. 计算公开值并交换:
    Alice根据自己选择的秘密整数a以及公开参数pg,计算出公开值A=ga mod p,然后把A发送给Bob;与此同时,Bob根据自己的秘密整数b以及公开参数pg,计算掉出公开值B= gb mod p,然后将B发送给Alice。在这个过程中,即便有窃听者截获了A和B的值,由于离散对数问题的困难性(很难由A反向推算出a,由B反向推算出b),窃听者很难获取到关键的秘密信息。
  4. 计算共享密钥:
    Alice在收到Bob发送过来的B后,利用自己的秘密整数a和接收到的B计算共享密钥,KA=Bamod p;Bob在收到Alice发送过来的A后,利用自己的秘密整数b和接收到的A计算共享密钥KB=Ab mod p。通过数学推导可以发现,KA和KB是相等的,即KA=KB= gab mod p。这个相等的值就是双方协商出来的共享密钥,后续双方就可以利用这个共享密钥进行对称加密等安全的通信操作。

代码

import java.util.HashSet;
import java.util.Set;

public class Diffie_Hellman密钥交换协议 {
    public static void main(String[] args) {
        /* 生成一个大素数p和它的本原根g */
        int p = 997;
        int g = PrimitiveRootsCalculator(p);

        /* A和B各自生成一个秘密整数a和b,且a,b<p-1 */
        int a = 5;
        int b = 6;

        /* A和B各自计算公开值A和B */
        int A = fun(g, a, p);
        int B = fun(g, b, p);

        /* 计算A和B的共享密钥(即会话密钥) */
        int Ka = fun(B, a, p);
        int Kb = fun(A, b, p);

        System.out.println("Ka = " + Ka + " Kb= " + Kb);
    }

    /* 计算一个数p的本原根 */
    static int PrimitiveRootsCalculator(int p) {
        /* 本原根满足 1< g < p */
        int g = 2;
        for (g = 2; g < p; g++) {
            Set<Integer> residues = new HashSet<>();
            /* 求p-1次模,看这p-1个模是否涵盖了1-p的所有数 */
            for (int i = 1; i < p; i++) {
                int residue = fun(g, i, p);
                residues.add(residue);
            }

            if (residues.size() == p - 1) {
                break;
            }
        }
        return g;
    }

    /* 快速幂算法,求g的n次幂模p */
    static int fun(int g, int n, int p) {
        int res = 1;
        g %= p;
        while (n > 0) {
            if ((n & 1) == 1) {
                res = (res * g) % p;
            }
            g = (g * g) % p;
            n >>= 1;
        }
        return res;
    }

}

关于代码中的fun函数部分的算法解释,可以看我写的另一篇文章:快速指数算法和高阶求模溢出问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秋窗7

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值