介绍Diffie-Hellman(简称DH)是密钥交换算法之一。DH目前最重要的应用场景之一就是在HTTPS的握手阶段,客户端和服务端使用DH算法交换对称密钥。下面将简单介绍一下DH的数学基础,然后举例说明如何在nodejs中使用DH相关的API。数论基础要理解DH算法,需要掌握一定的数论基础。有兴趣的可以进一步研究推导过程,或者只记住下面的结论,然后进入下一节。假设Y=a^Xmodp,当X已知时,很容易计算出Y;当Y已知时,很难计算出X;(a^Xamodp)^Xbmodp=a^(Xa*Xb)modp握手步骤说明假设客户端和服务器选择两个质数a和p(都是public),然后客户端:选择自然数Xa,Ya=a^Xamodp,将Ya发送给服务器;客户端:选择自然数Xb,Yb=a^Xbmodp,将Yb发送给客户端;客户端:计算Ka=Yb^Xamodp服务器:计算Kb=Ya^XbmodpKa=Yb^Xamodp=(a^Xbmodp)^Xamodp=a^(Xb*Xa)modp=(a^Xamodp)^Xbmodp=Ya^Xbmodp=Kb可以看出,虽然client,Server端并不知道对方的Xa和Xb,但是他们已经计算出相等的秘密。Nodejs代码示例结合前面总结的介绍,我们来看下面的代码。关键点之一是客户端和服务器使用相同的素数a和p。varcrypto=require('crypto');varprimeLength=1024;//质数p的长度vargenerator=5;//素数a//创建客户端的DH实例varclient=crypto.createDiffieHellman(primeLength,generator);//生成公私钥对,Ya=a^XamodpvarclientKey=client.generateKeys();//在服务器端创建一个DH实例,使用相同的素数a,pvarserver=crypto.createDiffieHellman(client.getPrime(),client.getGenerator());//生成公私钥对,Yb=a^XbmodpvarserverKey=server.generateKeys();//计算Ka=Yb^XamodpvarclientSecret=client.computeSecret(server.getPublicKey());//计算Kb=Ya^XbmodpvarserverSecret=server.computeSecret(client.getPublicKey());//因为质数p是动态生成的,每次都不一样//但是clientSecret===serverSecretconsole.log(clientSecret.toString('hex'));console.log(serverSecret.toString('hex'));了解Deffie-Hellman密钥交换算法的相关链接Diffie-Hellman密钥在NodeJS中交换安全消息使用ECDHKeylessSSL:TheNittyGrittyTechnicalDetails
