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

 
 

Diffie-Hellman 算法的更多相关文章

  1. 深入浅出Diffie–Hellman

    一.作者 这个密钥交换方法,由惠特菲尔德·迪菲(Bailey Whitfield Diffie).马丁·赫尔曼(Martin Edward Hellman)于1976年发表. 二.说明 它是一种安全协 ...

  2. 浅析Diffie–Hellman

    一.作者 这个密钥交换方法,由惠特菲尔德·迪菲(Bailey Whitfield Diffie).马丁·赫尔曼(Martin Edward Hellman)于1976年发表. 二.说明 它是一种安全协 ...

  3. Diffie–Hellman key exchange

    General overview[edit]   Illustration of the idea behind Diffie–Hellman key exchange Diffie–Hellman ...

  4. Node.js 内置模块crypto加密模块(4) Diffie Hellman

    Diffie-Hellman( DH ):密钥交换协议/算法 ( Diffie-Hellman Key Exchange/Agreement Algorithm ) 百科摘录: Diffie-Hell ...

  5. openssl之DH(Diffie–Hellman)加密

    //加密机制初始化 g_HDMgr.init(); //对方的public key BIGNUM* peerPubKey = NULL; peerPubKey = BN_bin2bn((unsigne ...

  6. HTTPS 和 SSL/TLS 协议:密钥交换(密钥协商)算法及其原理

    转自:https://blog.csdn.net/andylau00j/article/details/54583769 本系列的前一篇,咱们聊了“密钥交换的难点”以及“证书体系”的必要性.今天这篇来 ...

  7. 理解 HTTPS 的工作原理

    目标读者:理解HTTP协议,对称和非对称加密,想要了解HTTPS协议的工作原理. 读完本文,你能明白 什么是HTTPS,TLS(SSL),TLS和HTTPS是什么关系? 什么是证书和数字签名,它们是如 ...

  8. App安全之网络传输安全

    移动端App安全如果按CS结构来划分的话,主要涉及客户端本身数据安全,Client到Server网络传输的安全,客户端本身安全又包括代码安全和数据存储安全.所以当我们谈论App安全问题的时候一般来说在 ...

  9. APP安全--网络传输安全 AES/RSA/ECC/MD5/SHA

    移动端App安全如果按CS结构来划分的话,主要涉及客户端本身数据安全,Client到Server网络传输的安全,客户端本身安全又包括代码安全和数据存储安全.所以当我们谈论App安全问题的时候一般来说在 ...

  10. MySSL HTTPS 评级 B 升 A+

    背景 MySSL 提供了免费的网站 HTTPS 安全评级服务,然后我用我的网站 https://hellogithub.com,测试了一下.发现安全评级为 B,最高为 A+.下面是记录我的网站从 B ...

随机推荐

  1. 企业级服务元年:iClap高效解决手游更新迭代问题

    2006年至今,手游市场经历了不少变革,从WAP站到2009年智能手机时代来临,2012大量资本涌入国内手游行业,到2014年手游市场趋于成熟,细分市场成为追逐热门,在2015年优胜劣汰的资本寒冬浪潮 ...

  2. Entity Framework 数据生成选项DatabaseGenerated(转)

    在EF中,我们建立数据模型的时候,可以给属性配置数据生成选项DatabaseGenerated,它后有三个枚举值:Identity.None和Computed. Identity:自增长 None:不 ...

  3. 对Spring Bean了解一二

    这之前从未听说过Spring Bean,今天因为学习的<Java核心36讲>其中一篇涉及到了这个内容,因自己基础薄弱,杨晓峰老师讲的内容需要一定的基础才能看懂,故在网上搜罗一些我能理解的关 ...

  4. Java中使用OpenSSL生成的RSA公私钥进行数据加解密

    当前使用的是Linux系统,已经按装使用OpenSSL软件包, 一.使用OpenSSL来生成私钥和公钥 1.执行命令openssl version -a 验证机器上已经安装openssl 1 open ...

  5. Apache HttpClient4使用教程

    基于HttpClient 4.5.2 执行GET请求 CloseableHttpClient httpClient = HttpClients.custom() .build(); Closeable ...

  6. POI之Excel导入

    1,maven配置 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-oox ...

  7. 2017-2018-1 JaWorld 团队作业--冲刺6

    2017-2018-1 JaWorld 团队作业--冲刺6(20162308) 实现 由于我在冲刺部分负责的是类之间的耦合,所以我就介绍一下本次游戏的总体实现. 我们定义了Sprite类,即精灵类,游 ...

  8. mdio rgmii mac phy简单了解

    MDIO(Management Data Input/Output),对G比特以太网而言,串行通信总线称为管理数据输入输出 (MDIO). 该总线由IEEE通过以太网标准IEEE 802.3的若干条款 ...

  9. POJ 3169 Layout(差分约束+最短路)题解

    题意:有一串数字1~n,按顺序排序,给两种要求,一是给定u,v保证pos[v] - pos[u] <= w:二是给定u,v保证pos[v] - pos[u] >= w.求pos[n] - ...

  10. Python学习札记(二十三) 函数式编程4 sorted

    参考:sorted NOTE 1.sorted,快速排序,时间复杂度O(nlogn)渐进最优. #!/usr/bin/env python3 L = [] for i in range(10): L. ...