zoukankan      html  css  js  c++  java
  • Diffie-Hellman 算法

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

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

         DH 算法的安全性体现在:在有限域上计算离散对数非常困难。

         离散对数 :定义素数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密钥交换算法不进行认证对方。利用数字签名可以解决中间人攻击的缺陷。

    演示程序(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   2147483648 //Bigger the number the slower the algorithm

    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   = 0x94c49514;

      LFSR(x);
      rnd^=GetRTSC()^x;
      ROT(rnd,7);

      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 =  GenerateRandomNumber() % MAX_PRIME_NUMBER;

     //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;
    }

     
     
  • 相关阅读:
    Jmeter +Maven+jenkins+eclipse 接口自动化测试
    感知机
    第1章 统计学习方法概论
    java jdk安装 以及myeclipse安装
    邻接表
    c语言 文件写入和读取
    c++ string
    线程-run和start
    Transfer learning across two sentiment classes using deep learning
    层次遍历
  • 原文地址:https://www.cnblogs.com/ttzm/p/6104139.html
Copyright © 2011-2022 走看看