Diffie_Hellman 密钥商议算法

Diffie-Hellman 算法描述: 目前被许多商业产品交易采用。

DH 算法为公开的密钥算法,发明于1976年。该算法不能用于加密或解密,而是用于密钥的传输和分配。

     DH 算法的安全性体现在:在有限域上计算离散对数非常困难,或者说:已知gx 和gy,若不知道x和y,则计算gxy是困难的。

     离散对数 :定义素数p的原始根(primitive root)为这样一个数,它能生成1~p-1所有数的一个数。现设a为p的原始根,则

a mod p, a2 mod p,…,ap-1 mod p

   两两互不相同,构成一个1~p-1的全体数的一个排列。对于任意数b及素数p的原始根a,可以找到一个唯一的指数i,满足

b=ai mod p, 0<=i<=p-1

   则称指数i为以a为底、模P的b的离散对数。

算法描述:
假如Alice 和 Bob在不安全的网络上进行协商共同的密码:
1.Alice和Bob先说好一个大素数p和它的原始根a
2.Alice随机产生一个数x,
 计算X=ax mod p, 然后把X发给Bob;
3.   Bob秘密产生一个随机数y,计算Y=ay mod p, 然后把Y发给Alice;
4.Alice计算k=Yx mod p;
5.Bob计算k*=Xy mod p;

因为

k=Yx mod p= (ayx mod p=(a x)y mod p=X y mod p= k*

所以  k= k*

不安全线路上的窃听者只能得到a、p、X、Y,除非能计算离散对数x和y,否则将无法得到密钥k。因此,k为Alice和Bob独立计算出的密钥。

缺点:DH密钥交换算法易受到中间人攻击。

中间人攻击 描述:

(1)                       Alice 公开发送值a和p给Bob,攻击者Carol截获这些值,随即把自己产生的公开值发给Bob。

(2)                       Bob 公开发送值a和p给Alice,又被 Carol截获,随即把自己产生的公开值发给Alice。

(3)                       Alice 和Carol计算出两人之间的共享密钥k1。

(4)                       Bob 和Carol计算出两人之间另一个的共享密钥k2。

受到中间人Carol攻击后,Alice用密钥k1给Bob发送消息,Carol截获后用k1解密就可读取消息,然后将获得的明文消息用k2加密(加密前对消息可能做某些修改,即主动攻击),然后发给Bob。对Bob发给Alice的消息,Carol用同样的手法读取和修改。

造成中间人攻击得逞的原因是:DH密钥交换算法不进行认证对方。利用数字签名可以解决中间人攻击的缺陷。

  1 //演示程序(VC6.0)
  2
  3 //----------Diffie-Hellman.h---------
  4
  5 #define LFSR(n)    {if (n&1) n=((n^0x80000055)>>1)|0x80000000; else n>>=1;}
  6 #define ROT(x, y)  (x=(x<<y)|(x>>(32-y)))
  7 #define MAX_RANDOM_INTEGER 2147483648 //Should make these numbers massive to be more secure
  8 #define MAX_PRIME_NUMBER   2147483648 //Bigger the number the slower the algorithm
  9
 10 class Diffie_Hellman{
 11 public:
 12  Diffie_Hellman();
 13  int CreatePrimeAndGenerator();
 14  unsigned __int64 GetPrime();
 15  unsigned __int64 GetGenerator();
 16  unsigned __int64 GetPublicKey();
 17  void ShowValue(unsigned __int64 key);
 18  unsigned __int64 GetKey(unsigned __int64 HisPublieKey);
 19  int SetPrimeAndGenerator(unsigned __int64 Prime,unsigned __int64 Generator);
 20 private:
 21  __int64 GetRTSC( void );
 22  unsigned __int64 GenerateRandomNumber(void);
 23  __int64 XpowYmodN(__int64 x, __int64 y, __int64 N);
 24  bool IsItPrime (__int64 n, __int64 a) ;
 25  bool MillerRabin (__int64 n, __int64 trials);
 26  unsigned __int64 GeneratePrime();
 27  int CreatePrivateKey();
 28  int CreatePublicKey();
 29  int GenerateKey(unsigned __int64 HisPublicKey);
 30  unsigned __int64 p; //素数
 31  unsigned __int64 g; //对应的本原根
 32  unsigned __int64 X; //私钥
 33  unsigned __int64 Y; //公钥
 34  unsigned __int64 Key;//通讯密钥
 35 };
 36
 37 --------------Diffie-Hellman.cpp--------------
 38
 39 #include "Diffie-Hellman.h"
 40 #include<iostream>
 41 Diffie_Hellman::Diffie_Hellman(){
 42  p=0;
 43  g=0;
 44  X=0;
 45  Y=0;
 46  Key=0;
 47 }
 48
 49 __int64 Diffie_Hellman::GetRTSC( void )
 50 {
 51  int tmp1 = 0;
 52  int tmp2 = 0;
 53
 54  __asm
 55  {
 56   RDTSC;   // Clock cycles since CPU started
 57   mov tmp1, eax;
 58   mov tmp2, edx;
 59  }
 60
 61  return ((__int64)tmp1 * (__int64)tmp2);
 62 }
 63 unsigned __int64 Diffie_Hellman::GenerateRandomNumber(void)
 64 {
 65   static unsigned long rnd = 0x41594c49;
 66   static unsigned long x   = 0x94c49514;
 67
 68   LFSR(x);
 69   rnd^=GetRTSC()^x;
 70   ROT(rnd,7);
 71
 72   return (unsigned __int64)GetRTSC() + rnd;
 73 }
 74
 75 __int64 Diffie_Hellman::XpowYmodN(__int64 x, __int64 y, __int64 N)
 76 {
 77  __int64 tmp = 0;
 78  if (y==1) return (x % N);
 79
 80  if ((y&1)==0)
 81  {
 82   tmp = XpowYmodN(x,y/2,N);
 83   return ((tmp * tmp) % N);
 84  }
 85  else
 86  {
 87   tmp = XpowYmodN(x,(y-1)/2,N);
 88   tmp = ((tmp * tmp) % N);
 89   tmp = ((tmp * x) % N);
 90   return (tmp);
 91  }
 92 }
 93
 94 bool Diffie_Hellman::IsItPrime (__int64 n, __int64 a)
 95 {
 96  __int64 d = XpowYmodN(a, n-1, n);
 97  if (d==1)
 98   return true;
 99  else
100   return false;
101
102 }
103
104 bool Diffie_Hellman::MillerRabin (__int64 n, __int64 trials)
105 {
106  __int64 a = 0;
107
108  for (__int64 i=0; i<trials; i++)
109  {
110   a = (rand() % (n-3))+2;// gets random value in [2..n-1]
111
112   if (IsItPrime (n,a)==false)
113   {
114    return false;
115    //n composite, return false
116   }
117  } return true; // n probably prime
118 }
119
120 unsigned __int64 Diffie_Hellman::GeneratePrime()
121 {
122  unsigned __int64 tmp = 0;
123
124  tmp =  GenerateRandomNumber() % MAX_PRIME_NUMBER;
125
126  //ensure it is an odd number
127  if ((tmp & 1)==0)
128   tmp += 1;
129
130  if (MillerRabin(tmp,5)==true) return tmp;
131
132  do
133  {
134   tmp+=2;
135  } while (MillerRabin(tmp,5)==false);
136
137  return tmp;
138 }
139 int Diffie_Hellman::CreatePrimeAndGenerator()// 产生素数p,和它的本原根g
140 {
141  unsigned __int64 q;
142  bool f=true;
143  while(f){
144   p=GeneratePrime();
145   q=p*2+1;
146   if(MillerRabin(q,5)==true)
147    f=false;
148  }
149  f=true;
150  while(f){
151   g=GenerateRandomNumber() % (p-2);
152   if(XpowYmodN(g, 2, p)!=1 && XpowYmodN(g, q, p)!=1)
153    f=false;
154  }
155  return 0;
156 }
157
158 unsigned __int64 Diffie_Hellman::GetPrime(){
159  return p;
160 }
161 unsigned __int64 Diffie_Hellman::GetGenerator(){
162  return g;
163 }
164
165 int Diffie_Hellman::CreatePrivateKey(){
166   X=GenerateRandomNumber() %(p-1);
167  return 0;
168 }
169
170 int Diffie_Hellman::CreatePublicKey(){
171  //先设置私钥
172  if(X==0)
173   CreatePrivateKey();
174  Y=XpowYmodN(g, X, p);
175  return 0;
176 }
177 unsigned __int64 Diffie_Hellman::GetPublicKey(){
178  if(Y==0) CreatePublicKey();
179  return Y;
180 }
181 void Diffie_Hellman::ShowValue(unsigned __int64 key){
182  char s[20];
183  _i64toa(key,s,10);
184  std::cout<<s<<std::endl;
185 }
186
187 int Diffie_Hellman::GenerateKey(unsigned __int64 HisPublicKey){
188  Key=XpowYmodN(HisPublicKey, X, p);
189  return 0;
190 }
191
192 unsigned __int64 Diffie_Hellman::GetKey(unsigned __int64 HisPublicKey){
193  if(Key==0)
194   GenerateKey(HisPublicKey);
195  return Key;
196 }
197
198 int Diffie_Hellman::SetPrimeAndGenerator(unsigned __int64 Prime,unsigned __int64 Generator){
199  p=Prime;
200  g=Generator;
201  return 0;
202 }
203
204 ----------------Main.cpp------------
205
206 #include<iostream>
207 #include "Diffie-Hellman.h"
208 using namespace std;
209
210 int main(){
211  unsigned __int64 p=0,g=0,Alice_Y,Bob_Y,Alice_key,Bob_key;
212  char prime[20],generator[20],sAlice_key[20],sBob_key[20];
213  Diffie_Hellman Alice,Bob;
214  Alice.CreatePrimeAndGenerator();
215  p=Alice.GetPrime();
216  g=Alice.GetGenerator();
217  _i64toa(p,prime,10);
218  _i64toa(g,generator,10);
219  cout<<"prime:"<<prime<<endl<<"generator:"<<generator<<endl;
220  Bob.SetPrimeAndGenerator(p,g);
221  //p=Bob.GetPrime();
222  //g=Bob.GetGenerator();
223  //_i64toa(p,prime,10);
224  //_i64toa(g,generator,10);
225  //cout<<"prime:"<<prime<<endl<<"generator:"<<generator<<endl;
226  Alice_Y=Alice.GetPublicKey();
227  //_i64toa(Alice_Y,prime,10);cout<<prime<<endl;
228  Bob_Y=Bob.GetPublicKey();
229  //_i64toa(Bob_Y,prime,10);cout<<prime<<endl;
230  Alice_key=Alice.GetKey(Bob_Y);
231  //_i64toa(Alice_key,prime,10);cout<<prime<<endl;
232  Bob_key=Bob.GetKey(Alice_Y);
233  //_i64toa(Bob_key,prime,10);cout<<prime<<endl;
234  _i64toa(Alice_key,sAlice_key,10);
235  _i64toa(Bob_key,sBob_key,10);
236  cout<<sAlice_key<<endl<<sBob_key<<endl;
237  return 0;
238 }
时间: 2024-10-14 17:15:27

Diffie_Hellman 密钥商议算法的相关文章

Diffie-Hellman密钥协商算法

一.概述 Diffie-Hellman密钥协商算法主要解决秘钥配送问题,本身并非用来加密用的:该算法其背后有对应数学理论做支撑,简单来讲就是构造一个复杂的计算难题,使得对该问题的求解在现实的时间内无法快速有效的求解(computationally infeasible ). 理解Diffie-Hellman密钥协商的原理并不困难,只需要一点数论方面的知识既可以理解,主要会用到简单的模算术运算.本原根.费马小定理.离散对数等基础数论的知识.在现代密码学中的基础数论知识梳理中已经对这些知识做了必要的

消息摘要算法-HMAC算法

一.简述 mac(Message Authentication Code,消息认证码算法)是含有密钥散列函数算法,兼容了MD和SHA算法的特性,并在此基础上加上了密钥.因此MAC算法也经常被称作HMAC算法.关于hmac算法的详情可以参看RFC 2104(http://www.ietf.org/rfc/rfc2104.txt),这里包含了HmacMD5算法的C语言实现. 这里需要说明的是经过mac算法得到的摘要值也可以使用十六进制编码表示,其摘要值得长度与实现算法的摘要值长度相同.例如 Hmac

KeeLoq算法深入剖析

KeeLoq算法深入剖析   请支持原创,尊重原创,转载请注明出处:http://blog.csdn.net/kangweijian(来自kangweijian的csdn博客)   1       KeeLoq算法介绍 1.1  KeeLoq运算规则 KeeLoq算法的核心思想就是用8byte密钥加密4byte明文,从而得到4byte密文或者用8byte密钥解密4byte密文,还原出原4byte明文.KeeLoq算法演算过程需要定义一个数据寄存器,用于存放4byte明文y31~0或者4byte密

消息摘要算法-MAC算法系列

一.简述 mac(Message Authentication Code,消息认证码算法)是含有密钥散列函数算法,兼容了MD和SHA算法的特性,并在此基础上加上了密钥.因此MAC算法也经常被称作HMAC算法.关于hmac算法的详情可以参看RFC 2104(http://www.ietf.org/rfc/rfc2104.txt),这里包含了HmacMD5算法的C语言实现. 这里需要说明的是经过mac算法得到的摘要值也可以使用十六进制编码表示,其摘要值得长度与实现算法的摘要值长度相同.例如 Hmac

linux学习之路之加密类型及其相关算法

加密类型及其相关算法 随着互联网越演越烈,互联网上的各种攻击层出不穷,因此在互联网上相互传递的信息越来越不安全,因此为了防止用户在互联网上传递的数据被窃取,因此我们很有必须加强传递的数据的安全性. 数据的安全性主要包括以下三个方面: 数据的机密性:保证传递的数据不被读取 要想使传递的数据不被读取,可以对这些数据进行加密,因为默认这些数据是以明文来传递的 整个加密过程可以这么来理解: 加密:plaintext--->转换规则--->ciphertext 解密:ciphertext--->转

常见的加密和解密算法—DES

一.DES加密概述 DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来.需要注意的是,在某些文献中,作为算法的DES称为数据加密算法(Data Encryption Algorithm,DEA),已与作为标准的DES区分开来. DES入口参数 DES算法的入口参数有三个:Key.Data.Mode.其中Key为

git库添加密钥

$ssh-keygen -t rsa -C "${email}"    #"-t rsa"表示使用密钥的加密类型,还可以为dsa;"-C"设置注释文字(RSA支持变长密钥的算法.DSA数字签名算法是标准的数字签名标准) 生成.ssh/id_rsa          密钥 和.ssh/id_rsa.pub      公钥  cat id_rsa.pub--添加到github的ssh keys 1.SSH客户端提前将SSH公钥存储到SSH服务器上,然

什么是私有密钥密码技术——密钥加密算法采用同一把密钥进行加密和解密

什么是私有密钥密码技术 私有密钥(Symmetric Key),又叫对称密钥.密钥加密算法采用同一把密钥进行加密和解密.它的优点是加密和解密速度非常快,但密钥的分发和管理比较困难.信息的发送者和接收者必须明确同一把密钥.因此,必须进行密钥交流,这通常需要其他更安全的信道来传送密钥.另外,每一对用户都需要有自己的一个独一无二的密钥.因此,如果一个发送者与很多人通信,就需要管理很多密钥.主要的对称密钥加密算法有DES.3DES.RC2.RC4.RC5.Blowtish和CAST等.在VPN中常用的有

SM4算法

由于实现简单,SM4算法非常适合在智能数据卡.物联网传感节点等对面积和成本要求比较严格的场合使用.SM4算法是对称加密算法,也是分组算法,其分组长度和密钥长度均为128比特,即加密强度为128位.加密算法和密钥扩展算法都采用32轮非线性迭代结构.SM4算法如图所示,具体步骤如下: