Node.js如何使用Diffie-Hellman密钥交换算法详解


Posted in Javascript onSeptember 05, 2017

简介

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

下面会先简单介绍DH的数理基础,然后举例说明如何在nodejs中使用DH相关的API。下面话不多说了,来一起看看详细的介绍吧。

数论基础

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

  • 假设 Y = a^X mod p,已知X的情况下,很容易算出Y;已知道Y的情况下,很难算出X;
  • (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。

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 密钥交换算法

迪菲-赫尔曼密钥交换

Secure messages in NodeJSusing ECDH

Keyless SSL: The Nitty Gritty Technical Details

Javascript 相关文章推荐
JavaScript函数、方法、对象代码
Oct 29 Javascript
javascript中创建对象的三种常用方法
Dec 30 Javascript
给事件响应函数传参数的四种方式小结
Dec 05 Javascript
extjs 分页使用jsp传递数据示例
Jul 29 Javascript
js中使用replace方法完成某个字符的转换
Aug 20 Javascript
Javascript 引擎工作机制详解
Nov 30 Javascript
EasyUI学习之Combobox级联下拉列表(2)
Dec 29 Javascript
ES6新特性四:变量的解构赋值实例
Apr 21 Javascript
Ionic3实现图片瀑布流布局
Aug 09 Javascript
vue路由守卫及路由守卫无限循环问题详析
Sep 05 Javascript
JS实现轮播图效果
Jan 11 Javascript
JavaScript forEach中return失效问题解决方案
Jun 01 Javascript
javascript观察者模式实现自动刷新效果
Sep 05 #Javascript
js使用generator函数同步执行ajax任务
Sep 05 #Javascript
vue如何使用 Slot 分发内容实例详解
Sep 05 #Javascript
详解Vue2.0 事件派发与接收
Sep 05 #Javascript
JavaSctit 利用FileReader和滤镜上传图片预览功能
Sep 05 #Javascript
jQuery实现注册会员时密码强度提示信息功能示例
Sep 05 #jQuery
JSON在Javascript中的使用(eval和JSON.parse的区别)详细解析
Sep 05 #Javascript
You might like
php 验证码制作(网树注释思想)
2009/07/20 PHP
windows7下安装php的php-ssh2扩展教程
2014/07/04 PHP
Firefox outerHTML实现代码
2009/06/04 Javascript
js获取元素在浏览器中的绝对位置
2010/07/24 Javascript
体验js中splice()的强大(插入、删除或替换数组的元素)
2013/01/16 Javascript
jQuery中读取json文件示例代码
2013/05/10 Javascript
jquery中get和post的简单实例
2014/02/04 Javascript
使用jQuery不判断浏览器高度解决iframe自适应高度问题
2014/12/16 Javascript
JS实现向表格中动态添加行的方法
2015/03/30 Javascript
jQuery图片左右滚动代码 有左右按钮实例
2016/06/20 Javascript
JS实现漂亮的时间选择框效果
2016/08/20 Javascript
jQuery EasyUI中的日期控件DateBox修改方法
2016/11/09 Javascript
给Easyui-Datebox设置隐藏或者不可用的解决方法
2017/05/26 Javascript
JS+canvas绘制的动态机械表动画效果
2017/09/12 Javascript
如何抽象一个Vue公共组件
2017/10/17 Javascript
vue 添加vux的代码讲解
2017/11/30 Javascript
jQuery niceScroll滚动条错位问题的解决方法
2018/02/03 jQuery
深入浅出理解JavaScript闭包的功能与用法
2018/08/01 Javascript
AngularJS自定义表单验证功能实例详解
2018/08/24 Javascript
Vue2.x通用编辑组件的封装及应用详解
2019/05/28 Javascript
关于vue3.0中的this.$router.replace({ path: '/'})刷新无效果问题
2020/01/16 Javascript
JavaScript单线程和任务队列原理解析
2020/02/04 Javascript
JS关闭子窗口并且刷新上一个窗口的实现示例
2020/03/10 Javascript
js实现弹幕墙效果
2020/12/10 Javascript
Python统计纯文本文件中英文单词出现个数的方法总结【测试可用】
2018/07/25 Python
关于Python3爬虫利器Appium的安装步骤
2020/07/29 Python
css3圆角边框和边框阴影示例
2014/05/05 HTML / CSS
澳大利亚领先的在线机械五金、园艺和存储专家:Edisons
2018/03/24 全球购物
Oral-B荷兰:牙医最推荐的品牌
2020/02/25 全球购物
JENNIFER BEHR官网:各种耳环和发饰
2020/06/07 全球购物
加拿大著名的奢侈品购物网站:SSENSE(支持中文)
2020/06/25 全球购物
文件中有一组整数,要求排序后输出到另一个文件中
2012/01/04 面试题
cf收人广告词大全
2014/03/14 职场文书
难忘的一课教学反思
2014/04/30 职场文书
主婚人致辞精选
2015/07/28 职场文书
解决Springboot PostMapping无法获取数据的问题
2022/05/06 Java/Android