首先是前段时间我在公众号里被人批(dui)评(gang)了,大概意思就是:你别老整那ECDH又是椭圆又是素数啥的,你就说这玩意实际项目中怎么用就完了,咱们不想听那些,那些咱们都懂都精通,并且你还太监了,你本身看看是否是太监了,ECDH写到上一篇明显还没完,结果到如今了还没下文,你本身说是否是太监了,你本身说。php
其次是实际上本篇内容实际上和ECDH没有半毛钱关系,通篇都是DH(少了EC两个字母),不过在项目中实际应用的业务逻辑写法、道理都是同样晒儿的。你如今能够暂时认为DH就是ECDH的“ 少了两个字母版本 ”。用DH的最主要缘由是啥呢,由于时间有限,我优先写了DH的经常使用语言库文件,目前可用,ECDH的一根毛都没有写,因此只能用DH演示。node
最后是再次强调一遍,做为一篇正经的文章,我须要再次科普一下DH是啥意思。git
不少都觉得DH是Daemon Hunter(恶魔猎手)的简称,然而并非。Daemon Hunter是真实名称叫作伊利丹,是个瞎子同时又是法玛丽奥(就是老鹿)的兄dei。他暗恋白虎(就是那种真的白虎)泰兰德,然而泰兰德却嫁给了老鹿,事情大概就是这么一回事。
在咱们这里DH则是Diffie-Hellman的简称,二位大爷的照片我之前贴过,如今不得再也不贴一遍:程序员
上图告诉咱们头发长短与职业无关,douyin上那些自觉得get到程序员梗的短视频真的是LOWB到一塌糊涂。github
在正式开始前以前,我仍是要说明一下用DH的初衷是什么或者说这个东西是来解决什么问题的。接着上篇的故事(点击这里)说:redis
咱们引入DH就是为了解决上面的问题。然而,DH或ECDH并不能解决中间人攻击问题,这个要搞明白了。算法
因此,在正式开始以前,我必须先安利我和东北大嫖客还有巨蛀以及阿尼特写的DH库,github连接是这个,下面我将利用这些DH库们进行demo演示。json
https://github.com/ti-dh
(明眼人已经看出来我是来骗star的)
目前这个库提供了纯PHP、C实现的PHP扩展、Java版,列个表格吧:api
先说下服务端和客户端进行协商地总体流程,很是很是简单:服务器
整个协商流程中,只有第二步和第三步会发生数据交互。第二步是API下发p、g、server-num给客户端;第三步是客户端向API提交client-num数据;最后一步,对称加解密用的key就已经计算出来用于生产环境了。
下面我用世界上最好的语言演示一下如何使用这个鬼东西,客户端咱们用什么演示呢?客户端也依然使用世界上最好的语言来演示。首先,大家把上面github里的库文件集成到大家API里,我这里集成完毕后代码以下:
<?php class DhController extends BaseController{ private $dh = null; // 将DH库初始化进来呀... public function init() { $this->dh = new Dh(); } // 这就是上图中的第二步:客户端访问这个API获取g p 和 server-num public function getdhbasedataAction() { $ret = $this->dh->getdhbasedata(); echo json_encode( $ret ); } // 这就是上图中的第三步:客户端经过这个api提交client-num参数 public function postdhclientdataAction() { if ( $this->getRequest()->isPost() ) { if ( empty( $_POST['client_number'] ) || !is_numeric( $_POST['client_number'] ) ) { exit( json_encode( array( 'code' => -1, 'message' => 'wrong parameters', ) ) ); } $ret = $this->dh->postdhclientdata( $_POST ); echo json_encode( array( 'key' => $ret, ) ); } } }
<?php require __DIR__ . '/vendor/autoload.php'; use \Curl\Curl; $curl = new Curl(); // 初始化客户端数据,随机一个便可~ $client_number = mt_rand( 100000, 999999 ); // 一、第一步,获取服务器的p、g和server_number $ret = $curl->get( 'https://xxxx.ooo/dh/getdhbasedata' ); $ret = json_decode( $ret, true ); $p = $ret['p']; $g = $ret['g']; $server_number = $ret['server_number']; // 二、第二步,根据服务器获取到的数据计算出client-number $process_client_number = gmp_powm( $g, $client_number, $p ); // 三、第三步,将计算事后的client-number发送给服务器 // 那个demo里已经有完美的演示了,多看代码 $ret = $curl->post( 'https://xxxx.ooo/dh/postdhclientdata', array( 'client_number' => gmp_strval( $process_client_number ), ) ); $ret = json_decode( $ret, true ); // 四、第四步,根据server-number,client-number和p 计算出公共密钥K $key = gmp_powm( $server_number, $client_number, $p ); echo PHP_EOL."DH非对称密钥产生交换:".PHP_EOL; echo 'client计算出的public key : '.$key.PHP_EOL; echo 'server计算出的public key : '.$ret['key'].PHP_EOL.PHP_EOL;
客户端文件保存client.php,而后php client.php执行一下,结果大家感觉一下:
同样有没有?!计算出来的都同样,有没有?!!
上图中那么一坨长的不能整的让人看了就以为恶心呕吐的数字就是API和客户端分别计算出来的对称加解密的密钥了,请注意实际使用过程当中,服务器千万不要把这个数据返回给客户端,demo里这么作就是为了演示而已,用的时候本身也须要动动脑子的。
然而,事情每每不会说就是这么简单就能够了,若是在生产环境使用,仍是须要继续完善一些细节的。
我发誓,这是关于DH或ECDH的最后一篇文章了,之后我不再会写任何与这两个英文缩写相关的东西了,我说都是真的,我保证说到作到。