成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

關(guān)于PHP加解密之終扯到ECDH了(API安全加強(qiáng)篇三)

lcodecorex / 733人閱讀

摘要:很明顯,非對(duì)稱加密的極大的消耗成了一種瓶頸。其中,利用非對(duì)稱加密的方案大概就是我前面說的那樣,偽代碼已經(jīng)展示過了。

其實(shí),前面兩篇翻來覆去只為叨逼叨叨逼叨兩件事情:

對(duì)稱加解密,典型算法有AES、DES、3DES等等

非對(duì)稱加解密,典型的算法有RSA、DSA、ECDH等等

但是,我知道大家最討厭在看這種文章的時(shí)候冒出來的一坨“橢圓曲線”、“素?cái)?shù)”、“質(zhì)數(shù)”等等這樣的玩意,反正看也看不懂,理解也理解不了,背也背不過,所以我索性就不寫這些玩意,一點(diǎn)兒都不寫,不裝任何逼(然而實(shí)際上我背過了,我最近一直在搞線性代數(shù),所以對(duì)數(shù)學(xué)比原來稍微敏感了一些)。

寫到這里后,就有刁民、php泥腿子自以為已經(jīng)掌握了高科技,隨便從github上扒兩個(gè)庫(kù)下來跑了跑test就開始四處裝逼,聲稱自己精通對(duì)稱加密算法和非對(duì)稱加密算法,尤其是在面試的時(shí)候,上去就是跟面試官一頓糊弄,糊弄住了就要5萬(wàn),糊弄不了要5千。然而我要告訴你的是,你應(yīng)該接繼續(xù)往下看,這樣的話你在面試的時(shí)候,糊弄住了就可以張口要8萬(wàn),糊弄不了也能最低要8千!比原來要5000整整多了3000!而且我提供的這份裝逼指南還是免費(fèi)的!

今天我們從一個(gè)實(shí)際需求作為出發(fā)點(diǎn),比如你是API開發(fā)人員(當(dāng)然了,作為只有十來個(gè)人的小公司,你還得兼職運(yùn)維,不過工資只按開發(fā)算,運(yùn)維的活兒算是你友情贊助給老板的),然后老板兼PM向你提出了一個(gè)比較嚴(yán)峻的問題,大概意思就是“公司的項(xiàng)目是個(gè)非常牛逼的項(xiàng)目,一年后公司是要上市的,你必須要加密了數(shù)據(jù),讓BAT和TMD都無法抄襲我們!然后你就能買車買房!”,你表示十分認(rèn)可。由于你已經(jīng)看過了我前面兩篇文章,再加上老板一再?gòu)?qiáng)調(diào)“我們這個(gè)是牛逼的項(xiàng)目,遲早要上市”,所以你就準(zhǔn)備用高安全性的非對(duì)稱加密來解決這個(gè)問題。

具體做法就是服務(wù)器生成一對(duì)公私鑰,然后再生成一對(duì)公私鑰給所有客戶端公用。比如用戶登陸API,接口文檔大概如下:

API : https://www.so.com/api/user/login
METHOD : POST
PROTOCOL : 將數(shù)據(jù)以JSON形式,全部放入到http body體中,key叫做mzip
DATA : {
  "username" => "xitele",
  "password" => "qiangdadaoniyongyuancaibuchulaishiduoshao"
}

然后客戶端執(zhí)行登陸的偽代碼如下:

var username string = "xitele"
var password string = md5("123456")
// 將數(shù)據(jù)生成json
var data = jsonize( hashMap(
  "username" : username,
  "password" : password
) )
// 用服務(wù)器公鑰,將數(shù)據(jù)加密
var encryptData = RSA.encrypt( "服務(wù)端的公鑰", data )
// 再次封裝數(shù)據(jù)為json
var lastJson = jsonize( hashMap(
  "mzip" => encryptData
) )
// 提交數(shù)據(jù)
http.post( "https://www.so.com/api/user/login", lastJson, function() {
  // ... ... do something ...
} )

服務(wù)器端使用世界上最好的語(yǔ)言來實(shí)現(xiàn)的,所以代碼你會(huì)覺得十分眼熟:

prepare( "select * from user where username=:username" );
$sth->bindParam( ":username", $aDecryptData["username"], PARAM_STR );
$pdo->execute();
$aUser = $pdo->fetch();
if ( $aUser["password"] != $aDecryptData["password"] ) {
  echo json_encode( array(
    "code" => 0,
    "msg" => "登陸成功"
  ) );
}
else {
  echo json_encode( array(
    "code" => 10002,
    "msg" => "登陸失敗"
  ) );
}

上線后,發(fā)現(xiàn)倒也沒啥大問題了,就是明顯服務(wù)器CPU負(fù)載特別高,客戶端也感覺有點(diǎn)兒卡。很明顯,非對(duì)稱加密的CPU極大的消耗成了一種瓶頸。于是你找老板申請(qǐng)服務(wù)區(qū)費(fèi)用,老板當(dāng)場(chǎng)表示非常理解,大手一揮就給你批了300塊錢并表示隨意揮霍,把服務(wù)器升級(jí)成最牛逼的服務(wù)器。

當(dāng)然了,都跟我學(xué)習(xí)了這么久了你應(yīng)該馬上就意味到300塊代表著什么,300塊頂多代表能組兩個(gè)局兒... ...

當(dāng)然了,API那里也好交代,全線降級(jí)為AES對(duì)稱,CPU瞬間就下來了,又不是不能用.. ...

當(dāng)然了,300塊組個(gè)五人局兒應(yīng)該還是可以的,除了你和我,再拉上柱子跟老趙,最后再帶上陳旭,局兒上除了吃飯,就額外討論一下關(guān)于這個(gè)問題的解決方案。

局兒后,我神神秘秘地告訴你說“這特么簡(jiǎn)單,我給你講,你服務(wù)器先隨機(jī)生成一個(gè)AES對(duì)稱加密用的密鑰,然后利用客戶端的RSA公鑰加密后傳給客戶端,客戶端再通過自己的RSA私鑰解密得到這個(gè)AES對(duì)稱密鑰,然后再用這個(gè)AES對(duì)稱密鑰進(jìn)行后續(xù)的加解密即可,然后你可以給這個(gè)AES密鑰設(shè)定一個(gè)有效期,比如五分鐘,當(dāng)過期后,就再次利用上面的流程申請(qǐng)新的AES密鑰即可!這樣,不僅保證了AES密鑰的安全,還能解決了性能問題!”

鋪墊這么長(zhǎng),終于能扯出來今天的討論關(guān)鍵點(diǎn)了:密鑰協(xié)商/交換!這就是我們今天的核心話題了。

先說下為什么會(huì)出現(xiàn)密鑰協(xié)商和交換這種玩意,其實(shí)就是為了避免密鑰在網(wǎng)絡(luò)上的傳輸被劫持導(dǎo)致的安全問題,前兩句話的潛臺(tái)詞就是“這個(gè)世界上存在著一種即便我不告訴你,你也能知道我想告訴你什么的心有靈犀解決方案”。

密鑰協(xié)商交換一般常用的有如下幾種方案:

利用RSA等非對(duì)稱加密技術(shù)進(jìn)行交換,也就是300塊的局兒上那個(gè)方案

利用專門伺候密鑰交換需求的交換算法,比如DH算法,全稱叫做Diffie-Hellman密鑰交換。Diffie和Hellman分別是兩個(gè)大叔的名字(注意,此二位是數(shù)學(xué)家),是他們合伙搞出來的這個(gè)算法,DH算法先于RSA出現(xiàn)。

其中,利用非對(duì)稱加密的方案大概就是我前面說的那樣,偽代碼已經(jīng)展示過了。那么DH到底是個(gè)什么玩意呢?

下面我們玩一個(gè)比較簡(jiǎn)單的數(shù)字游戲:

1、元首和古德里安都同時(shí)選擇100這個(gè)數(shù)字,其他人知不知道無所謂
2、元首隨機(jī)出了一個(gè)數(shù)字9,然后將9乘以數(shù)字100,得到900,其他人能不能知道無所謂
3、古德里安隨機(jī)出了一個(gè)數(shù)3,然后將3乘以數(shù)字100,得到300,其他人能不能知道無所謂
4、元首將900扔給古德里安
5、古德里安將300扔給元首
到這里后,元首手里有的數(shù)據(jù)有100、9、300,古德里安手里的數(shù)據(jù)有100、3、900,然后兩個(gè)人此時(shí)只需要默默地做下面這一步:
元首:9 * 300 = 2700
古德里安:3 * 900 = 2700
OK了,就2700了

雙方都在僅僅是遠(yuǎn)遠(yuǎn)地確認(rèn)了一下眼神,說了一句話(彼此交換300和900),就已經(jīng)同時(shí)得到2700這個(gè)相同的數(shù)字。辣么,2700就是雙方后面進(jìn)行通信時(shí)候?qū)?shù)據(jù)進(jìn)行加密的密鑰了。同樣,雙方可以為這個(gè)密鑰算一個(gè)過期時(shí)間,比如五分鐘后,然后過期后重新協(xié)商出一個(gè)新的即可!而且,即便有其他人知道了雙方選擇的是100,也知道了元首給古德里安傳了900,也知道了古德里安給元首穿了300,然而并沒有什么卵用,因?yàn)樗€是不知道對(duì)方最終使用的密鑰(也就是2700)是多少。

當(dāng)然了,現(xiàn)實(shí)中真正的DH算法選擇公共數(shù)字、隨機(jī)數(shù)字可不是這么簡(jiǎn)單的,而且雙方最終計(jì)算這個(gè)密鑰的時(shí)候也不會(huì)像上面那個(gè)例子中那么輕松簡(jiǎn)單做一下乘法而已。

具體人家怎么算得,我就不寫了,反正網(wǎng)上到處都有,而且無論我寫出來還是不寫出來,反正你們都不看,畢竟,這玩意是數(shù)學(xué)家要搞的玩意。

RSA的庫(kù)前面我從github上扒過,也test過了,所以RSA就不演示了。然而,DH的咱們一起從github上扒一個(gè)下來玩玩來驗(yàn)證一下我們剛才講的簡(jiǎn)單理論。

PHP的一個(gè)DH庫(kù),GITHUB鏈接:https://github.com/jcink/diff...


將上述代碼保存為index.php,然后php index.php 32執(zhí)行一下,結(jié)果如下,你們感受一下:

我們看到這個(gè)庫(kù)順帶打印了一坨log,作為從來不研究底層的廣大泥腿子來說,我們只需要關(guān)注最后一行“Shared Key : 101451040”,這個(gè)就是服務(wù)端和客戶端協(xié)商出來的密鑰了,也就是意味著后面API的通信過程中使用101451040對(duì)數(shù)據(jù)加解密即可。

好了,以上是DH算法。其實(shí),圈里那些仁兄在看到今天標(biāo)題中含有DH的時(shí)候心里就應(yīng)該有數(shù)了,這傻逼天天在微信群里安利ECDH,今兒特么終于看到DH兩個(gè)字母了,總算有點(diǎn)兒眉毛了。辣么,我天天在群里安利的ECDH到底是什么玩意。

具體原理怎么回事,反正我這次是真是連背都背不過了,不過,你可以簡(jiǎn)單認(rèn)為ECDH是DH的升級(jí)版本,畢竟多了兩個(gè)字母。其實(shí)ECDH是ECC算法和DH算法二合一體,媽蛋,又特么冒出來一個(gè)ECC,好了好了,就當(dāng)我沒說。

然后還是老套路,我們從github上扒一個(gè)庫(kù)下來簡(jiǎn)單跑一下test,這樣以后就可以出去裝逼要8萬(wàn)工資了,傳送門:https://github.com/Querdos/EC...

computeSecret( $gudelian->getPublic() );
$gudelian->computeSecret( $xitele->getPublic() );

// shareKey1 和 shareKey2 就是協(xié)商出來的密鑰
$shareKey1 = $xitele->getSecret();
echo $shareKey1.PHP_EOL;
$shareKey2 = $gudelian->getSecret();
echo $shareKey2.PHP_EOL;

// 我們用gmp cmp來對(duì)比是否為同一個(gè)密鑰
if ( 0 == gmp_cmp( $shareKey1, $shareKey2 ) ) {
  echo "一樣".PHP_EOL;
}
else {
  echo "不一樣".PHP_EOL;
}

// 除此之外,這個(gè)ecdh庫(kù)比dh那個(gè)庫(kù)多了一個(gè)驗(yàn)證數(shù)據(jù)簽名驗(yàn)證,可以檢驗(yàn)數(shù)據(jù)是否被篡改!
$msg = "hello world";
$signature = $xitele->signMessage( $msg );
if ( $gudelian->verifySignature( $signature, $xitele->getPublic(), $msg ) ) {
  echo "驗(yàn)證數(shù)據(jù)簽名成功".PHP_EOL;
}
else {
  echo "驗(yàn)證數(shù)據(jù)簽名失敗".PHP_EOL;
}
exit;

將代碼保存為index.php,然后php index.php執(zhí)行結(jié)果如下圖所示:

通過上面代碼我們可以看出來,可以直接背誦一個(gè)結(jié)論,就是DH和ECDH都可以實(shí)現(xiàn)密鑰協(xié)商交換,但是ECDH還可以對(duì)數(shù)據(jù)進(jìn)行簽名,另一方可以對(duì)數(shù)據(jù)進(jìn)行驗(yàn)簽,從而可以判斷出數(shù)據(jù)在傳輸過程中是否被篡改!

好了,念念已久的ECDH終于入講了!以后我不會(huì)再在群里再叨叨這個(gè)了,祝你們幸福。

最近開了一個(gè)微信公眾號(hào):高性能API社區(qū),所有文章都先發(fā)這里

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/31422.html

相關(guān)文章

  • 我發(fā)誓這真的是最后一篇關(guān)于ECDH的文兒!(API安全強(qiáng)篇四)

    摘要:這種神奇的算法可以讓你服務(wù)器和客戶端在不傳輸該對(duì)稱密鑰的情況下就可以通過心有靈犀地方式各自計(jì)算出一個(gè)對(duì)稱密鑰,而且可以一樣,避免了該密鑰在網(wǎng)絡(luò)上流通,而且你可以隨意更換,過期時(shí)間定為分鐘,可謂是狠毒至極我們引入就是為了解決上面的問題。 首先是前段時(shí)間我在公眾號(hào)里被人批(dui)評(píng)(gang)了,大概意思就是:你別老整那ECDH又是橢圓又是素?cái)?shù)啥的,你就說這玩意實(shí)際項(xiàng)目中怎么用就完了,我...

    IntMain 評(píng)論0 收藏0
  • 我發(fā)誓這真的是最后一篇關(guān)于ECDH的文兒?。?em>API安全強(qiáng)篇四)

    摘要:這種神奇的算法可以讓你服務(wù)器和客戶端在不傳輸該對(duì)稱密鑰的情況下就可以通過心有靈犀地方式各自計(jì)算出一個(gè)對(duì)稱密鑰,而且可以一樣,避免了該密鑰在網(wǎng)絡(luò)上流通,而且你可以隨意更換,過期時(shí)間定為分鐘,可謂是狠毒至極我們引入就是為了解決上面的問題。 首先是前段時(shí)間我在公眾號(hào)里被人批(dui)評(píng)(gang)了,大概意思就是:你別老整那ECDH又是橢圓又是素?cái)?shù)啥的,你就說這玩意實(shí)際項(xiàng)目中怎么用就完了,我...

    Barrior 評(píng)論0 收藏0
  • 關(guān)于PHP解密的懶漢入門篇(API安全強(qiáng)篇一)

    摘要:由于密鑰被暴露了,所以必須換新的密鑰,元首這會(huì)兒只能走途徑告訴古德里安新的密鑰,這會(huì)兒逗逼的事情來了,如何對(duì)密鑰進(jìn)行加密。但是,有一點(diǎn)是值得說明,那就是無論是對(duì)稱加密還是非對(duì)稱加密,都頂不住用機(jī)器是強(qiáng)行暴力猜解私鑰。 懶漢 入門 這兩點(diǎn)就足以說明這篇文章不想要著有什么高端大氣的技術(shù)內(nèi)容,我跟你講,全是水。不可能有什么質(zhì)數(shù)素?cái)?shù)、橢圓曲線加密、迪菲-赫爾曼什么的,不可能有的。 首先我不...

    waterc 評(píng)論0 收藏0
  • 關(guān)于PHP解密的青年抬高篇(API安全強(qiáng)篇二)

    摘要:實(shí)際上這一篇和上一篇均可以看作是關(guān)于加解密的懶漢入門篇安全加強(qiáng)篇一的后續(xù),只不過側(cè)重點(diǎn)在于安全上?;氐缴掀Y(jié)果提到的問題,就是對(duì)稱加密的安全性要人命,非對(duì)稱加密的性能非常要人命。元首作為高智商罪犯,這種低級(jí)錯(cuò)誤是不可能犯的。 為什么標(biāo)題總是要帶上API安全關(guān)鍵字呢?因?yàn)槲蚁胛覙芬狻?實(shí)際上這一篇和上一篇均可以看作是《關(guān)于PHP加解密的懶漢入門篇(API安全加強(qiáng)篇一)》》)的后續(xù),只不過...

    wujl596 評(píng)論0 收藏0
  • 關(guān)于PHP解密的青年抬高篇(API安全強(qiáng)篇二)

    摘要:實(shí)際上這一篇和上一篇均可以看作是關(guān)于加解密的懶漢入門篇安全加強(qiáng)篇一的后續(xù),只不過側(cè)重點(diǎn)在于安全上。回到上篇結(jié)果提到的問題,就是對(duì)稱加密的安全性要人命,非對(duì)稱加密的性能非常要人命。元首作為高智商罪犯,這種低級(jí)錯(cuò)誤是不可能犯的。 為什么標(biāo)題總是要帶上API安全關(guān)鍵字呢?因?yàn)槲蚁胛覙芬狻?實(shí)際上這一篇和上一篇均可以看作是《關(guān)于PHP加解密的懶漢入門篇(API安全加強(qiáng)篇一)》》)的后續(xù),只不過...

    付倫 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<