一、DH密钥交换步骤
假设A和B需要共享一个对称密码的密钥,但双方之间的通信线路已被窃听。这时,A和B可以通过以下方法进行DH密钥交换,从而生成共享密钥。
1.A、B约定好两个数P和G
(P:一个大素数,G:本原根。P、G:可以公开,由A、B任意一方生成)
2.A挑选一个随机数A
(A:一个1~p-2的整数,只有A知道)
3.B挑选一个随机数B
(B:一个1~p-2的整数,只有A知道)
4.A将G的 A次方 mod P发给B,B将G的 B次方 mod P发给A(两数为公钥,可以公开)
5.A用B发过来的数计算A次方并求mod P,B用A发过来的数计算B次方并求mod P(该数就是共享密钥,A、B计算出相等的共享密钥)
(由于A、B保密,因此攻击者最多能够得到P、G、G的 A次方 mod P和G的 B次方 mod P。如果攻击者想要得到共享密钥,至少需要计算出A和B中的一个,这意味着需要求解离散对数问题,这在计算上是不可行的。)
二、实现例子:
1. A先选一个素数和一个底数,例如,素数p=23,底数g=5(底数可以任选),再选择一个秘密整数a=6,计算A=(g^a mod p)=8,然后大声告诉B:p=23,g=5,A=8;
2. B收到A发来的p,g,A后,也选一个秘密整数b=15,然后计算B=(g^b mod p)=19,并大声告诉A:B=19;
3. A自己计算出s=(B^a mod p)=2,B也自己计算出s=(A^b mod p)=2,因此,最终协商的密钥s为2。
三、实现代码(C++)
#include<iostream>
#include<cmath>
#include<iomanip>
#include<math.h>
#include<time.h>
using namespace std;
int mod(int x,int y,int z){
//把计算数据转为double类型,原因是int类型数据范围太小,double类型数据精度高、范围广
double s=pow(x,y);
double p=z*1.0;
int k=(int)(s/p);//double类型数据求余
int r=s-k*p;//把得到的结果转为int类型
return r;
}
int main(){
int P,G;//选择的大素数P和本原根G
int A,B;//A、B挑选的保密整数
int YA,YB;//A、B的公钥
int KA,KB;//A、B生成的共享密钥
int i;
cout<<"输入一个素数p:";cin >> P;
cout<<"输入一个本原根g:";cin >> G;
//输入例子A、B挑选的保密整数a、b
A=6;
B=15;
//A的公钥
YA=mod(G,A,P);
//B的公钥
YB=mod(G,B,P);
cout<<"A的公钥YA:"<<YA<<endl;
cout<<"B的公钥YB:"<<YB<<endl;
//KA、KB分别为A、B之间的共享密钥,KA=KB
KA=mod(YB,A,P);
KB=mod(YA,B,P);
cout<<"共享密钥key:(KA)"<<KA<<" 或 (KB)"<<KB<<endl;
system("pause");
return 0;
}
四、实现结果