其实前两篇文章重复了两件事:对称加解密,典型算法有AES、DES、3DES等非对称加密和解密,典型的算法有RSA、DSA、ECDH等。但是,我知道大家在看这种文章的时候很讨厌“椭圆曲线”、“素数”、“质数”等等诸如此类的东西,反正我看不懂,看不懂,背不下来,干脆不写这些东西,干脆不写,也不装被迫(但我实际上记住了它们,我最近一直在做线性代数,所以我对数学比以前更敏感了)。写到这里,有自以为掌握了高科技的骗子和php泥腿,随便从github上拿了两个库跑了测试,然后就开始假装精通对称加密算法和非对称加密。算法,尤其是在面试过程中,是为了愚弄面试官。被忽悠了,5万元,不忽悠,5000元。但是,我想告诉你的是,你应该继续阅读。这样,在面试的时候,如果你上当了,你开口要8万,如果不能上当,你最低要8000!比原来的5000多了3000!我提供的这个伪装指南是免费的!今天我们从一个实际需求出发。比如你是一个API开发人员(当然,作为一个只有十几个人的小公司,你不得不兼职做运维,但是工资只按开发计算,运维的工作andmaintenanceisyourfriendship.sponsoredtotheboss),然后boss和PM问了你一个比较严肃的问题,大概意思是“公司的项目是一个很牛逼的项目,一年后公司就要上市了,你必须数据加密,让BAT、TMD无法复制我们!那你就可以买车买房了!”,你很赞同。既然你看了我之前的两篇文章,而且老大一再强调“我们的项目牛逼,早晚会上市”,你打算用高安全性的非对称加密来解决这个问题。具体方法是服务端生成一对公私钥,再生成一对公私钥供所有客户端共享。例如用户登录API时,接口文档大致如下:body,key叫做mzipDATA:{'username'=>'xitele','password'=>'qiangdadaoniyongyuancaibuchulaishiduoshao'}然后客户端执行登录的伪代码如下:varusernamestring='xitele'varpasswordstring=md5('123456')//生成数据jsonvardata=jsonize(hashMap('username':username,'password':password))//用服务器公钥加密数据varencryptData=RSA.encrypt('server'spublickey',data)//再次封装数据为jsonvarlastJson=jsonize(hashMap('mzip'=>encryptData))//提交数据http.post('https://www.so.com/api/user/login',lastJson,function(){//......dosomething...})服务器端是使用世界上最好的语言实现的,所以代码看起来很熟悉:prepare("select*fromuserwhereusername=:username");$sth->bindParam(':username',$aDecryptData['username'],PARAM_STR);$pdo->execute();$aUser=$pdo->fetch();if($aUser['password']!=$aDecryptData['password']){echojson_encode(array('code'=>0,'msg'=>'登录成功'));}else{echojson_encode(array('code'=>10002,'msg'=>'登录失败'));}上网后发现什么都没有什么大问题?很明显服务器的CPU负载特别高,客户端也感觉有点卡。很明显,非对称加密巨大的CPU消耗已经成为瓶颈。于是你找老板申请服务区费用,老板当场表示理解,挥手批给你300元,说想花多少就花多少,升级了服务器到最强大的服务器。当然,跟着我学了这么久,你应该马上就明白300元是什么意思了,300元最多只能代表两轮。。。当然API也很容易解释,整行降级为AES对称,CPU会瞬间掉,也不是不能用。。。当然应该可以300元组个五人局,除了你我,然后拉柱子和老赵,最后拉陈徐顺,除了吃饭,我们还要商量解决这个问题的方法。赛后神秘地告诉你,“就这么简单,我告诉你,你的服务器先随机生成一个密钥进行AES对称加密,然后用客户端的RSA公钥加密后发送给客户端。,客户端通过自己的RSA私钥解密AES对称密钥,然后使用AES对称密钥进行后续加解密,然后可以给AES密钥设置一个有效期,比如5分钟,过期时,只需使用上述流程再次申请新的AES密钥!这样既保证了AES密钥的安全性,又解决了性能问题!”经过这么长时间的准备,今天的讨论终于可以拉出来了重点:密钥约定/交换!这是我们今天的核心话题。先说一下为什么会有密钥协商交换这种东西。其实就是为了避免网络上密钥传输被劫持而带来的安全问题。不用告诉你,你也能知道我想告诉你的默解。”密钥协商和交换有几种常用的方案:使用RSA等非对称加密技术进行交换,即300-blockboard使用了一种专门服务于密钥交换需求的交换算法,比如DH算法,全称叫做Diffie-Hellmankeyexchange,Diffie和Hellman是两个叔叔的名字(注意这两个是数学家),并且他们共同开发了这个算法,DH算法出现在RSA之前,其中使用非对称加密的方案大概就是我之前说的,伪代码已经展示了。那么DH到底是什么?我们来玩一个比较简单的数字游戏:1.元首和古德里安同时选择数字100,别人知道不重要,别人能知道不重要3.古德里安随机想出一个数字3,并且然后多把3乘以100得到300,别人能知道没关系4.元首把900扔给古德里安5.古德里安把300扔给元首后,元首手里的数据分别是100、9、300,古德里安手里的数据是100、3、900。那么两人只需要默默地做下面这一步:元首:9*300=2700古德里安:3*900=2700OK,是2700,双方只是远远的看了一眼,说了一句话(互相交换了300和900),同时得到了2700这个相同的数字。Hot,2700是后面双方通信时加密数据的密钥。同样,双方可以计算出这个key的一个过期时间,比如五分钟后,过期后再重新协商一个!而且,就算其他人知道双方选了100,也知道元首给了古德里安900,也知道古德里安给了元首300,但是没用,因为他还不知道对方使用的最终密钥是多少(即2700)。当然,真正的DH算法在现实中选择公众号和随机数并不是那么简单,而且双方在最终计算出密钥的时候,也不会像上面的例子那样简单的做乘法。我不会写人们如何计算它。反正网上到处都是,我写不写,反正你也不看。毕竟这东西是数学家想做的事情。我从github上拿了RSA库,之前测试过,所以RSA就不演示了。但是,DH,让我们从github上拿一个来玩一下,以验证我们刚才谈到的简单理论。PHP的DH库,GITHUB链接:https://github.com/jcink/diff...computeSecret($gudelian->getPublic());$gudelian->computeSecret($xitele->getPublic());//shareKey1和shareKey2是协商好的密钥$shareKey1=$xitele->getSecret();echo$shareKey1.PHP_EOL;$shareKey2=$gudelian->getSecret();echo$shareKey2.PHP_EOL;//我们用gmpcmp比较是否是同一个keyif(0==gmp_cmp($shareKey1,$shareKey2)){echo"same".PHP_EOL;}else{echo"different".PHP_EOL;}//另外这个ecdh库比dh库多了一个验证数据签名验证,可以检查数据是否被篡改!$msg="helloworld";$signature=$xitele->signMessage($msg);if($gudelian->verifySignature($signature,$xitele->getPublic(),$msg)){echo"验证数据签名Success".PHP_EOL;}else{echo"验证数据签名失败".PHP_EOL;}exit;将代码保存为index.php,然后执行phpindex.php,如下图所示:从上面的代码我们可以直接背出一个结论,DH和ECDH都可以实现密钥交换,但是ECDH也可以对数据进行签名,对方可以对数据进行校验,这样就可以判断数据在传输过程中是否被篡改了!好了,期待已久的ECDH终于来了!这个就不在群里说了,祝你们幸福。我最近开通了一个微信公众号公众号:高性能API社区,所有文章先发到这里
