## 简介

Diffie-Hellman(简称DH)是密钥交换算法之一,它的作用是保证通信双方在非安全的信道中安全地交换密钥。目前DH最重要的应用场景之一,就是在HTTPS的握手阶段,客户端、服务端利用DH算法交换对称密钥。

下面会先简单介绍DH的数理基础,然后举例说明如何在nodejs中使用DH相关的API。

## 数论基础

要理解DH算法,需要掌握一定的数论基础。感兴趣的可以进一步研究推导过程,或者直接记住下面结论,然后进入下一节。

1. 假设 Y = a^X mod p,已知X的情况下,很容易算出Y;已知道Y的情况下,很难算出X;
2. (a^Xa mod p)^Xb mod p = a^(Xa * Xb) mod p

## 握手步骤说明

假设客户端、服务端挑选两个素数a、p(都公开),然后

* 客户端:选择自然数Xa,Ya = a^Xa mod p,并将Ya发送给服务端;
* 服务端:选择自然数Xb,Yb = a^Xb mod p,并将Yb发送给客户端;
* 客户端:计算 Ka = Yb^Xa mod p
* 服务端:计算 Kb = Ya^Xb mod p

>Ka = Yb^Xa mod p
= (a^Xb mod p)^Xa mod p
= a^(Xb * Xa) mod p
= (a^Xa mod p)^Xb mod p
= Ya^Xb mod p
= Kb

可以看到,尽管客户端、服务端彼此不知道对方的Xa、Xb,但算出了相等的secret。

## Nodejs代码示例

结合前面小结的介绍来看下面代码,其中,要点之一就是client、server采用相同的素数a、p。

```javascript
var crypto = require('crypto');

var primeLength = 1024; // 素数p的长度
var generator = 5; // 素数a

// 创建客户端的DH实例
var client = crypto.createDiffieHellman(primeLength, generator);
// 产生公、私钥对,Ya = a^Xa mod p
var clientKey = client.generateKeys();

// 创建服务端的DH实例,采用跟客户端相同的素数a、p
var server = crypto.createDiffieHellman(client.getPrime(), client.getGenerator());
// 产生公、私钥对,Yb = a^Xb mod p
var serverKey = server.generateKeys();

// 计算 Ka = Yb^Xa mod p
var clientSecret = client.computeSecret(server.getPublicKey());
// 计算 Kb = Ya^Xb mod p
var serverSecret = server.computeSecret(client.getPublicKey());

// 由于素数p是动态生成的,所以每次打印都不一样
// 但是 clientSecret === serverSecret
console.log(clientSecret.toString('hex'));
console.log(serverSecret.toString('hex'));
```

## 相关链接

[理解 Deffie-Hellman 密钥交换算法](http://wsfdl.com/algorithm/2016/02/04/%E7%90%86%E8%A7%A3Diffie-Hellman%E5%AF%86%E9%92%A5%E4%BA%A4%E6%8D%A2%E7%AE%97%E6%B3%95.html)

[迪菲-赫尔曼密钥交换](https://zh.wikipedia.org/zh-cn/%E8%BF%AA%E8%8F%B2-%E8%B5%AB%E7%88%BE%E6%9B%BC%E5%AF%86%E9%91%B0%E4%BA%A4%E6%8F%9B)

[Secure messages in NodeJSusing ECDH](https://cafedev.org/article/2016/11/secure-messages-in-nodejs-using-ecdh/)

[Keyless SSL: The Nitty Gritty Technical Details](https://blog.cloudflare.com/keyless-ssl-the-nitty-gritty-technical-details/)

Nodejs进阶:使用DiffieHellman密钥交换算法的更多相关文章

  1. Diffie-Hellman密钥交换算法

    Diffie-Hellman密钥交换算法 之前做过的一个项目中用过DH算法(Diffie-Hellman),这种密钥交换技术的目的在于使得两个用户安全地交换一个共享密钥(shared secret)以 ...

  2. SSL/TLS协议详解(上):密码套件,哈希,加密,密钥交换算法

    本文转载自SSL/TLS协议详解(上):密码套件,哈希,加密,密钥交换算法 导语 作为一名安全爱好者,我一向很喜欢SSL(目前是TLS)的运作原理.理解这个复杂协议的基本原理花了我好几天的时间,但只要 ...

  3. DH 密钥交换算法

    1.引言 CSDN搞什么短信验证,7年的账号居然登陆不了,真心抓狂,WTF!!!! DH,全称为"Diffie-Hellman",这是一种确保共享KEY安全穿越不安全网络的方法,换 ...

  4. DH密钥交换算法

    DH密钥交换算法:DH的全称为Diffie-Hellman ,该算法可以在需要安全传输的前提下,确定双方的对称密钥,该算法的核心在于双方的私钥没有进入网络传输流程,根据对方的公钥和己方的私钥,可以计算 ...

  5. NodeJS学习笔记 进阶 (12)Nodejs进阶:crypto模块之理论篇

    个人总结:读完这篇文章需要30分钟,这篇文章讲解了使用Node处理加密算法的基础. 摘选自网络 Nodejs进阶:crypto模块之理论篇 一. 文章概述 互联网时代,网络上的数据量每天都在以惊人的速 ...

  6. nodejs进阶(6)—连接MySQL数据库

    1. 建库连库 连接MySQL数据库需要安装支持 npm install mysql 我们需要提前安装按mysql sever端 建一个数据库mydb1 mysql> CREATE DATABA ...

  7. nodejs进阶(4)—读取图片到页面

    我们先实现从指定路径读取图片然后输出到页面的功能. 先准备一张图片imgs/dog.jpg. file.js里面继续添加readImg方法,在这里注意读写的时候都需要声明'binary'.(file. ...

  8. nodejs进阶(3)—路由处理

    1. url.parse(url)解析 该方法将一个URL字符串转换成对象并返回. url.parse(urlStr, [parseQueryString], [slashesDenoteHost]) ...

  9. nodejs进阶(5)—接收请求参数

    1. get请求参数接收 我们简单举一个需要接收参数的例子 如果有个查找功能,查找关键词需要从url里接收,http://localhost:8000/search?keyword=地球.通过前面的进 ...

随机推荐

  1. 数位dp模板 [dp][数位dp]

    现在才想到要学数位dp,我是不是很弱 答案是肯定的 以一道自己瞎掰的题为模板 //题: //输入数字n //从0枚举到n,计算这n+1个数中含有两位数a的数的个数 //如12930含有两位数93 #i ...

  2. .Net中关于相等的问题

    在.Net框架中,如果您查看所有类型的的基类:System.Object类,将找到如下4个与相等判断的方法: static Equals() virtual Equals() static Refer ...

  3. 在CentOS7上部署OpenStack 步骤详解

    OpenStack作为一个由NASA(美国国家航空航天局)和Rackspace合作研发并发起的,开放源代码项目的云计算管理平台项目.具体知识我会在后面文章中做出介绍,本章主要按步骤给大家演示在Cent ...

  4. MySQL学习笔记(五):MySQL表级锁和行级锁

    一:概述 相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制.比如,MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking ...

  5. tcp netstat用法 TIME_WAIT状态解析 MTU以及MSS

    带着问题写博客 问题1:使用netstat查看有源TCP连接的状态时,经常会看到established状态,那么还有哪些状态,这些状态是如何变化的呢? 问题2:TIME_WAIT状态存在的必要? 问题 ...

  6. Android 内存检查

    Android 内存检查 本文简单介绍了如何使用 DDMS 和 MAT 工具来对 android 进行内存检查,了解 android 内存的具体占用情况. 步骤1. 使用 DDMS 观察内存的使用情况 ...

  7. Linux下 两台机器文件/文件夹 相互拷贝

    Linux下 两台机器文件/文件夹 相互拷贝 设有两台机器 :A:*.101及 B:*.102. 把A下的.temp/var/a.txt拷贝到B机器的/text/目录下: 进入B机器:scp root ...

  8. Android中的Activity

    Android四大组件 活动(Activity) 广播接收者(BroadCastReceiver) 服务(Service) 内容提供者(Contentprovider) Activity 先来看And ...

  9. HTML的正确入门姿势——基本结构与基本标签

    一.什么是HTML HTML是超文本标签语言,即网页的源码.而浏览器就是翻译解释HTML源码的工具. 二.HTML文档的结构 HTML文档主要包括三大部分:文档声明部分.<head>头部部 ...

  10. Java 冒泡排序的实现

    实现原理: 比较相邻的元素.如果第一个比第二个大,就交换他们两个. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对.在这一点,最后的元素应该会是最大的数. 针对所有的元素重复以上的步骤,除 ...