Diffie-Hellman 算法描述: 目前被许多商业产品交易采用。
HD 算法为公开的密钥算法,发明于1976年。该算法不能用于加密或解密,而是用于密钥的传输和分配。 


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

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

算法描述:
 假如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= (ay) x 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)                      
(2)                      
(3)                      
(4)                      
受到中间人Carol攻击后,Alice用密钥k1给Bob发送消息,Carol截获后用k1解密就可读取消息,然后将获得的明文消息用k2加密(加密前对消息可能做某些修改,即主动攻击),然后发给Bob。对Bob发给Alice的消息,Carol用同样的手法读取和修改。
造成中间人攻击得逞的原因是:DH密钥交换算法不进行认证对方。利用数字签名可以解决中间人攻击的缺陷。

演示程序(VC6.0)
----------Diffie-Hellman.h---------
#define LFSR(n)    {if (n&1) n=((n^0x80000055)>>1)|0x80000000; else n>>=1;}
 #define ROT(x, y)  (x=(x<<y)|(x>>(32-y)))
 #define MAX_RANDOM_INTEGER 2147483648 //Should make these numbers massive to be more secure
 #define MAX_PRIME_NUMBER  
class Diffie_Hellman{
 public:
  Diffie_Hellman();
  int CreatePrimeAndGenerator();
  unsigned __int64 GetPrime();
  unsigned __int64 GetGenerator();
  unsigned __int64 GetPublicKey();
  void ShowValue(unsigned __int64 key);
  unsigned __int64 GetKey(unsigned __int64 HisPublieKey);
  int SetPrimeAndGenerator(unsigned __int64 Prime,unsigned __int64 Generator);
 private:
  __int64 GetRTSC( void );
  unsigned __int64 GenerateRandomNumber(void);
  __int64 XpowYmodN(__int64 x, __int64 y, __int64 N);
  bool IsItPrime (__int64 n, __int64 a) ;
  bool MillerRabin (__int64 n, __int64 trials);
  unsigned __int64 GeneratePrime();
  int CreatePrivateKey();
  int CreatePublicKey();
  int GenerateKey(unsigned __int64 HisPublicKey);
  unsigned __int64 p; //素数
  unsigned __int64 g; //对应的本原根
  unsigned __int64 X; //私钥
  unsigned __int64 Y; //公钥
  unsigned __int64 Key;//通讯密钥
 };--------------Diffie-Hellman.cpp--------------
#include "Diffie-Hellman.h"
 #include<iostream>
 Diffie_Hellman::Diffie_Hellman(){
  p=0;
  g=0;
  X=0;
  Y=0;
  Key=0;
 }
__int64 Diffie_Hellman::GetRTSC( void )
 {
  int tmp1 = 0;
  int tmp2 = 0;
  
  __asm
  {
   RDTSC;   // Clock cycles since CPU started
   mov tmp1, eax;
   mov tmp2, edx;
  }return ((__int64)tmp1 * (__int64)tmp2);
 }
 unsigned __int64 Diffie_Hellman::GenerateRandomNumber(void)
 {
   static unsigned long rnd = 0x41594c49;
   static unsigned long x   LFSR(x);
   rnd^=GetRTSC()^x;
   return (unsigned __int64)GetRTSC() + rnd;
 }__int64 Diffie_Hellman::XpowYmodN(__int64 x, __int64 y, __int64 N)
 {
  __int64 tmp = 0;
  if (y==1) return (x % N);if ((y&1)==0)
  {
   tmp = XpowYmodN(x,y/2,N);
   return ((tmp * tmp) % N);
  }
  else
  {
   tmp = XpowYmodN(x,(y-1)/2,N);
   tmp = ((tmp * tmp) % N);
   tmp = ((tmp * x) % N);
   return (tmp);
  }
 }bool Diffie_Hellman::IsItPrime (__int64 n, __int64 a)
 {
  __int64 d = XpowYmodN(a, n-1, n);
  if (d==1)
   return true;
  else
   return false;
  
 }bool Diffie_Hellman::MillerRabin (__int64 n, __int64 trials)
 {
  __int64 a = 0;for (__int64 i=0; i<trials; i++)
  {
   a = (rand() % (n-3))+2;// gets random value in [2..n-1]
   
   if (IsItPrime (n,a)==false)
   {
    return false;
    //n composite, return false
   }
  } return true; // n probably prime
 }unsigned __int64 Diffie_Hellman::GeneratePrime()
 {
  unsigned __int64 tmp = 0;tmp = 
//ensure it is an odd number
  if ((tmp & 1)==0)
   tmp += 1;if (MillerRabin(tmp,5)==true) return tmp;
  
  do
  {
   tmp+=2; 
  } while (MillerRabin(tmp,5)==false);
   
  return tmp;
 }
 int Diffie_Hellman::CreatePrimeAndGenerator()// 产生素数p,和它的本原根g
 { 
  unsigned __int64 q;
  bool f=true;
  while(f){
   p=GeneratePrime();
   q=p*2+1;
   if(MillerRabin(q,5)==true)
    f=false;
  }
  f=true;
  while(f){
   g=GenerateRandomNumber() % (p-2);
   if(XpowYmodN(g, 2, p)!=1 && XpowYmodN(g, q, p)!=1)
    f=false;
  }
  return 0;
 }unsigned __int64 Diffie_Hellman::GetPrime(){
  return p;
 }
 unsigned __int64 Diffie_Hellman::GetGenerator(){
  return g;
 }int Diffie_Hellman::CreatePrivateKey(){
   X=GenerateRandomNumber() %(p-1);
  return 0;
 }int Diffie_Hellman::CreatePublicKey(){
  //先设置私钥
  if(X==0)
   CreatePrivateKey();
  Y=XpowYmodN(g, X, p);
  return 0;
 }
 unsigned __int64 Diffie_Hellman::GetPublicKey(){
  if(Y==0) CreatePublicKey();
  return Y;
 }
 void Diffie_Hellman::ShowValue(unsigned __int64 key){
  char s[20];
  _i64toa(key,s,10);
  std::cout<<s<<std::endl;
 }int Diffie_Hellman::GenerateKey(unsigned __int64 HisPublicKey){
  Key=XpowYmodN(HisPublicKey, X, p);
  return 0;
 }unsigned __int64 Diffie_Hellman::GetKey(unsigned __int64 HisPublicKey){
  if(Key==0)
   GenerateKey(HisPublicKey);
  return Key;
 }int Diffie_Hellman::SetPrimeAndGenerator(unsigned __int64 Prime,unsigned __int64 Generator){
  p=Prime;
  g=Generator;
  return 0;
 }----------------Main.cpp------------
#include<iostream>
 #include "Diffie-Hellman.h"
 using namespace std;
int main(){
  unsigned __int64 p=0,g=0,Alice_Y,Bob_Y,Alice_key,Bob_key;
  char prime[20],generator[20],sAlice_key[20],sBob_key[20];
  Diffie_Hellman Alice,Bob;
  Alice.CreatePrimeAndGenerator();
  p=Alice.GetPrime();
  g=Alice.GetGenerator();
  _i64toa(p,prime,10);
  _i64toa(g,generator,10);
  cout<<"prime:"<<prime<<endl<<"generator:"<<generator<<endl;
  Bob.SetPrimeAndGenerator(p,g);
  //p=Bob.GetPrime();
  //g=Bob.GetGenerator();
  //_i64toa(p,prime,10);
  //_i64toa(g,generator,10);
  //cout<<"prime:"<<prime<<endl<<"generator:"<<generator<<endl;
  Alice_Y=Alice.GetPublicKey();
  //_i64toa(Alice_Y,prime,10);cout<<prime<<endl;
  Bob_Y=Bob.GetPublicKey();
  //_i64toa(Bob_Y,prime,10);cout<<prime<<endl;
  Alice_key=Alice.GetKey(Bob_Y);
  //_i64toa(Alice_key,prime,10);cout<<prime<<endl;
  Bob_key=Bob.GetKey(Alice_Y);
  //_i64toa(Bob_key,prime,10);cout<<prime<<endl;
  _i64toa(Alice_key,sAlice_key,10);
  _i64toa(Bob_key,sBob_key,10);
  cout<<sAlice_key<<endl<<sBob_key<<endl;
  return 0;
 }