你們好,我是永強,就是老李以前常常給大家說的區塊鏈大神、大學肄業卻依然大公司iOS主程一波兒流、只生活在老李口中還沒有真實露面的騙錢高手、老王的左膀右臂 ——— 趙永強。我和尼古拉斯趙四之間並無什麼強關聯,我只是單方面認識他而已。php
以前老李企圖讓我發表一些關於如何進行高端騙工資騙錢的教程,被我義正言辭地拒絕了:css
畢竟是畢生絕學,不能就這麼垂手可得地教給大家
不事後面有時間我能夠給你們出一些關於「如何在公司混日子還能升職加薪」的入門級教程,傳男不傳女,獨家絕技!敬請期待!html
言歸正傳,那個一直以來我對加解密技術都是耿耿於懷的,由於不少年前有一次面試中被這東西給坑掉了,雖然我後來就本身對加解密中一些本身不懂的地方請教了對方並且他也沒有給我講清楚…面試
事情都過去好幾年了,本人自我感受已經必定程度掌握了一些關於加密的高端技術,由於決定出來裝一波兒逼,時間比較緊張,我打算趕在2020年農曆新年以前把逼裝完,大家要注意配合。算法
我知道老李以前在社區發表了一些關於加密啊、解密啊之類的東西,甚至還扯上了什麼DH什麼ECDH,又是質數又是橢圓曲線,不過這並不與本系列產生衝突,這並不重要,不要在乎這些細節,他那個too young too simple,sometimes naive…編程
這將是一個大概由四篇左右的文章組成的系列文章,因此在正式開始以前,我不得不強調一點 ——— 以下這幾門學科的基礎理論知識:ubuntu
你並不須要具有。。。安全
不過你總得知道除了html和css以外的任意一門編程語言。儘管本人精通上到CLanguage下到Perl之類的各類語言,可是本文將採用世界上最好的語言進行一些程序演示,後面老李可能會使用CLanguage和Golang進行其餘語言的演示補充。php7
簡單說來呢,加解密技術就是分爲兩大類:dom
其中,常見的對稱加解密算法有DES、3DES、AES;而非對稱加解密技術比較典型的則是RSA,就是什麼公鑰私鑰證書什麼亂七八糟的。
咱們先從對稱加解密開始,粗暴地說呢,對稱加解密就是「加密和解密的時候用同一個密碼」,聽起來就很是對稱,有沒有?
用圖表達一下就是:
最一開始的時候,我朝人民通常都是傾向於使用「天王蓋地虎」,「寶塔鎮河妖」這種加解密技術;然而,美帝用了一種叫作DES的技術進行對稱加解密,這玩意一度成爲業界通用的對稱加解密技術,銀行、五角大樓都愛用這玩意,惋惜好景不長、世風日下、世態炎涼,這玩意的破解成本愈來愈低愈來愈低~~ 因而,爲了續命,就又有一些白鬍子老頭給DES打補丁,縫縫補補搞出來一個玩意叫作3DES,繼續用,又不是不能用…這個顧名思義就好了,別打我,真的:3DES就是用DES處理(注意是處理,我沒說是加密)了三次的意思。就目前看來,3DES實際上用的可能也並非十分普遍了,因此若是你們在選擇對稱加解密技術的時候,儘可能避開DES和3DES就能夠了。
呵呵,喜新厭舊的沙雕人類…雖然DES已經沒人用了,但畢竟也是輝煌過,我以爲仍是得動手錶演一波兒。咱們知道,在php7裏,原來的mcrypt系列加解密已經被放棄掉了,官方建議咱們使用openssl系列來進行加解密,因此確保你的PHP環境裏安裝了openssl標準擴展。
<?php // 這個函數打印出來openssl支持的全部加密方法以及模式的組合 $arr_ava_methods = openssl_get_cipher_methods(); print_r( $arr_ava_methods );
文件保存成test.php後,執行一把:php test.php | grep des,結果大家感覺一下:
其中帶有ede的,好比des-ede*這樣的就表示是3DES。還有這麼多奇奇怪怪的後綴是什麼含義?回頭再說…又不是不能用。
篩選一下,咱們看des(非des3)有幾種帶着尾巴的具體方法:
咱們先用傳統des方法繼續進行裝逼表演:
<?php // 咱們就選用des-ecb方法進行一次des加密 $ava_methods = openssl_get_cipher_methods(); $my_method = 'des-ecb'; if ( !in_array( $my_method, $ava_methods ) ) { exit( '錯誤的加密方法'.PHP_EOL ); } $key = "123456"; $data = "helloMOTO"; echo "明文:".$data.PHP_EOL; $enc_data = openssl_encrypt( $data, $my_method, $key ); echo "密文:".$enc_data.PHP_EOL; $dec_data = openssl_decrypt( $enc_data, $my_method, $key ); echo "明文:".$dec_data.PHP_EOL;
保存爲test.php執行一把:
完美!就像老王的meshbox同樣,完美!
簡單解析一下:
換個方法繼續一下:咱們使用openssl_get_cipher_methods()函數獲取到可使用的全部des加密方法,而後簡單判斷一下咱們選用的方法是否在其中;緊接着咱們用123456做爲密碼,helloMOTO做爲明文內容,openssl_encrypt()就是加密函數,openssl_decrypt()就是解密函數,具體的函數原型出門左拐查手冊,總之一切都是這麼的完美!
<?php // 咱們就選用des-ecb方法進行一次des加密 $ava_methods = openssl_get_cipher_methods(); $my_method = 'des-cbc'; if ( !in_array( $my_method, $ava_methods ) ) { exit( '錯誤的加密方法'.PHP_EOL ); } $key = "123456"; $data = "helloMOTO"; echo "明文:".$data.PHP_EOL; $enc_data = openssl_encrypt( $data, $my_method, $key ); echo "密文:".$enc_data.PHP_EOL; $dec_data = openssl_decrypt( $enc_data, $my_method, $key ); echo "明文:".$dec_data.PHP_EOL;
執行一波兒,結果以下圖:
並不完美,報錯了,一個warning級的錯誤,雖然並不影響加密和解密,可是畢竟是報錯了,錯誤原文我複製粘貼過來,大家感覺下:
PHP Warning: openssl_encrypt(): Using an empty Initialization Vector (iv) is potentially insecure and not recommended in /home/ubuntu/lab/test.php on line 10
大概意思就是:用了一個並不推薦並且不安全的空iv在test.php的第十行。我正在翻譯的這句的時候,已經精通英語的老李在旁邊跟我說「你這翻譯也太硬了,要學會人性化,看好了,一看你這就是沒上過全日制大學本科的惡果」:
PHP警告:openssl_encrypt():iv向量最好別是空的,不推薦這麼用,並且這樣並不安全~
什麼是iv向量?先拋開這個問題,我先寫一段代碼,讓他能跑起來:
<?php $ava_methods = openssl_get_cipher_methods(); $my_method = 'des-cbc'; if ( !in_array( $my_method, $ava_methods ) ) { exit( '錯誤的加密方法'.PHP_EOL ); } // 處理iv向量的兩行代碼 $iv_length = openssl_cipher_iv_length( $my_method ); $iv = openssl_random_pseudo_bytes( $iv_length ); $key = "123456"; $data = "helloMOTO"; echo "明文:".$data.PHP_EOL; $enc_data = openssl_encrypt( $data, $my_method, $key, 0, $iv ); echo "密文:".$enc_data.PHP_EOL; $dec_data = openssl_decrypt( $enc_data, $my_method, $key, 0, $iv ); echo "明文:".$dec_data.PHP_EOL;
注意到八、九、10和1五、17兩行,均爲iv向量作了改動,而後此次代碼保存了運行一波兒:
完美!就像老王的meshbox同樣,完美!
那麼,在des加解密中,咱們遺留了兩個問題: