乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      PHP的OpenSSL加密擴展學(xué)習(一):對稱加密

       硬核項目經(jīng)理 2021-05-31

      PHP的OpenSSL加密擴展學(xué)習(一):對稱加密

      我們已經(jīng)學(xué)過不少 PHP 中加密擴展相關(guān)的內(nèi)容了。而今天開始,我們要學(xué)習的則是重點中的重點,那就是 OpenSSL 加密擴展的使用。為什么說它是重點中的重點呢?一是 OpenSSL 是目前 PHP 甚至是整個開發(fā)圈中的數(shù)據(jù)加密事實標準,包括 HTTPS/SSL 在內(nèi)的加密都是它的實際應(yīng)用,二是 OpenSSL 提供了對稱和非對稱加密的形式,也就是我們?nèi)粘V凶钇毡榈膬煞N加密方式,這都是我們需要掌握的內(nèi)容。

      那么,它和 Hash 類的加密有什么不同嗎?Hash 類的加密是單向的不可逆轉(zhuǎn)的加密,加密后的內(nèi)容是 16進制 的 Hash 串,我們只能通過彩虹表去反推明文內(nèi)容,所以只要加上鹽值或者多套兩層加密,就非常難逆向破解出來了。因此,Hash 加密通常會用于用戶的密碼保存上,即使數(shù)據(jù)庫泄露了用戶密碼也依然是安全的。而 OpenSSL 這種類型的對稱/非對稱加密則是可以通過某個關(guān)鍵字或者證書來進行正向加密和逆向解密的,原文都是可以得到的。下面我們就來具體說說對稱和非對稱加密的問題。

      什么是對稱和非對稱加密

      對稱加密,通常是通過一個 key(密鑰) 來對原文進行加密。也就是說,不管是服務(wù)端還是客戶端或是其它的任何對端,在兩端通信時,它們傳輸?shù)募用軆?nèi)容都必須要使用相同的 key 來進行加/解密操作。兩端都必須同時保存這樣一個 key 。估計大家也想到了,現(xiàn)在不管是 web 開發(fā)還是 app 開發(fā),代碼都是可以反編譯查看到源碼的。如果使用對稱加密的話,key 是很容易被獲取到的。不過,對稱加密的好處是速度非常快,不消耗資源。

      非對稱加密則是兩端持有不同的 key 。就像我們平常見到的最多的 https 證書,就是分別有 公鑰 和 私鑰 這兩個概念。一般我們會使用 公鑰 進行加密,然后使用 私鑰 進行解密,通常 公鑰 都是公開并發(fā)送給對方的,而私鑰是保存在自己這里的。也就是說,對方向我們發(fā)送數(shù)據(jù)的時候,使用我們給它的公鑰將數(shù)據(jù)進行加密,數(shù)據(jù)在傳輸過程中就非常安全,因為中間并沒有別人有可以解密這段數(shù)據(jù)的私鑰,直到我們接收到數(shù)據(jù)后使用自己的私鑰進行解密后就得到了原文數(shù)據(jù)。由于兩邊的密鑰內(nèi)容并不相同,所以相對于對稱加密來說,非對稱加密的安全性要高了很多。雖然說非對稱加密的算法和復(fù)雜度都比對稱加密提升了好幾個檔次,但相對于對稱加密的優(yōu)勢,在非對稱加密中,速度和性能也就成了它的瓶頸,特別是數(shù)據(jù)量大的情況下。另外,非對稱加密的數(shù)學(xué)原理是 大數(shù)難分解 問題,也就是越大的數(shù)越難進行因子分解,如果某個算法能在短時間內(nèi)破解這個問題的話,那么恭喜你,現(xiàn)代加密算法的基礎(chǔ)天花板就被你捅破了。

      對稱加密常用的算法有:AES 、DES 、3DES 、 IDEA 、 RC2 、 RC5 等,比較常用的是 AES 和 DES 。

      非對稱加密常用的算法有:RSA 、Elgamal 、ECC 等,RSA 非常常用和普遍,SSL 和一些證書算法都是基于 RSA 。

      為了系統(tǒng)安全我們應(yīng)該怎么辦?

      那么,我們有沒有折衷的方式來使用這兩種加密能力呢?當然有了,并且也是非常經(jīng)典的一種技術(shù):數(shù)字信封。

      其實意思非常簡單,就是利用這兩種加密方式各自的優(yōu)點。非對稱加密的安全性高,但速度慢,而且數(shù)據(jù)量越大速度越慢,那么我們就用它來加密對稱加密的 key ,通常這個 key 不會很大。然后實際的數(shù)據(jù)實體使用這個對稱加密的 key 來進行對稱加密提升速度。這樣,我們發(fā)送給客戶端時,就包括兩個內(nèi)容,一個是非對稱加密進行加密的 key ,一個使用對稱加密進行加密的數(shù)據(jù)內(nèi)容??蛻舳四玫叫畔⒑螅紫仁褂梅菍ΨQ加密的密鑰解碼出對稱加密的 key ,然后再使用這個 key 來解密最終的數(shù)據(jù)內(nèi)容。是不是說得很暈?我們通過一張圖來看看,或許大家就一目了然了。

      其中,公鑰和私鑰就不用多解釋了。會話密鑰就是我們的對稱加密算法的密鑰 key 。結(jié)合上面對數(shù)字信封傳輸過程的解釋,大家應(yīng)該就能看懂了吧。

      OpenSSL 擴展的對稱加密

      好了,介紹這么多理論知識,接下來還是回歸正題了,我們在 PHP 中如何實現(xiàn)對稱和非對稱加密呢?非常簡單,使用 OpenSSL 擴展就可以了。這個擴展也是隨 PHP 源碼一起發(fā)布的,編譯安裝的時候加上 --with-openssl 就可以了。當然,它也是需要系統(tǒng)環(huán)境中安裝 OpenSSL 軟件的,在各類操作系統(tǒng)中基本都已經(jīng)直接有了,如果沒有的話就自己安裝一下即可。最簡單的,在操作系統(tǒng)命令行看看有沒有 openssl 命令就可以看出當前系統(tǒng)有沒有安裝 OpenSSL 相關(guān)的軟件。

      [root@localhost ~]# openssl version
      OpenSSL 1.1.1 FIPS  11 Sep 2018

      今天,我們主要學(xué)習的還是比較簡單的對稱加密相關(guān)的函數(shù)。

      對稱加/解密實現(xiàn)

      $data = '測試對稱加密';
      $key = '加密用的key';
      $algorithm =  'DES-EDE-CFB';


      $ivlen = openssl_cipher_iv_length($algorithm);
      $iv = openssl_random_pseudo_bytes($ivlen);


      $password = openssl_encrypt($data, $algorithm, $key, 0, $iv);
      echo $password, PHP_EOL;
      // 4PvOc75QkIJ184/RULdOTeO8

      echo openssl_decrypt($password, $algorithm, $key, 0, $iv), PHP_EOL;
      // 測試對稱加密

      // Warning: openssl_encrypt(): Using an empty Initialization Vector (iv) is potentially insecure and not recommended

      openssl_encrypt() 就是加密數(shù)據(jù),它需要原文、算法和密鑰三個參數(shù),后面的參數(shù)是可選的,但是現(xiàn)在是推薦自己來定義 iv (向量) 參數(shù),所以如果沒有 iv 參數(shù)的話,會報一個警告信息。我們使用 openssl_cipher_iv_length() 來獲取當前算法需要的 iv 長度,然后使用 openssl_random_pseudo_bytes() 函數(shù)來生成一個隨機的符合算法長度的 iv 內(nèi)容。

      中間那個 0 的參數(shù)是指定標記的按位或值,它有兩個可選常量:OPENSSL_RAW_DATA 和 OPENSSL_ZERO_PADDING ,如果設(shè)置為 OPENSSL_RAW_DATA 加密后的數(shù)據(jù)將按照原樣返回(二進制亂碼內(nèi)容),如果設(shè)置為 OPENSSL_ZERO_PADDING ,加密后的數(shù)據(jù)將返回為 base64 之后的內(nèi)容。

      openssl_decrypt() 用于對數(shù)據(jù)進行解密,需要的參數(shù)基本和加密函數(shù)一致,只是原文數(shù)據(jù)換成了加密數(shù)據(jù)。

      在對稱加密中,我們還有一種  AEAD 密碼模式(GCM 或 CCM) ,在使用這種模式的算法時,我們需要多一參數(shù)。

      $algorithm =  'aes-128-gcm';
      $password = openssl_encrypt($data, $algorithm, $key, 0, $iv, $tags);
      echo $password, PHP_EOL;
      // dPYsR+sdP56rQ99CNxciah+N

      echo openssl_decrypt($password, $algorithm, $key, 0, $iv, $tags), PHP_EOL;
      // 測試對稱加密

      這個 $tags 是一個引用類型的參數(shù),也就是加密后會賦值到這個變量中,解密的時候也需要相同的這個驗證標簽。

      從加密解密的過程來看,如果我們要將這些信息保存在數(shù)據(jù)庫中,或者進行傳輸解密時,我們至少要保存或傳輸這幾個字段,加密使用的 iv ,加密使用的算法,以及 AEAD 模式的話加密所使用的驗證標簽,否則數(shù)據(jù)無法解密。

      對稱加密算法查詢

      print_r(openssl_get_cipher_methods());

      // Array
      // (
      //     [0] => AES-128-CBC
      //     [1] => AES-128-CBC-HMAC-SHA1
      //     [2] => AES-128-CFB
      //     [3] => AES-128-CFB1
      //     [4] => AES-128-CFB8
      //     [5] => AES-128-CTR
      //     [6] => AES-128-ECB
      //     [7] => AES-128-OFB
      //     [8] => AES-128-XTS
      //     [9] => AES-192-CBC
      //     [10] => AES-192-CFB
      //     [11] => AES-192-CFB1
      //     [12] => AES-192-CFB8
      //     ……
      // )

      在上面加/解密測試中所選取的算法就是從這個函數(shù)中找出來的,這個函數(shù)就是顯示當前環(huán)境下所有支持的算法列表。

      總結(jié)

      這篇文章的內(nèi)容有比較多的理論相關(guān)的知識,大家還是要多多地消化。使用 OpenSSL 實現(xiàn)加/解密的功能其實還是比較簡單的,畢竟東西都已經(jīng)幫我們封裝好了,我們只需要按照文檔來調(diào)用函數(shù)就可以了。學(xué)習,還是要理論結(jié)合實際,當然,更重要的是自己多動手!

      測試代碼:

      https://github.com/zhangyue0503/dev-blog/blob/master/php/202007/source/PHP%E7%9A%84OpenSSL%E5%8A%A0%E5%AF%86%E6%89%A9%E5%B1%95%E5%AD%A6%E4%B9%A0%EF%BC%88%E4%B8%80%EF%BC%89%EF%BC%9A%E5%AF%B9%E7%A7%B0%E5%8A%A0%E5%AF%86.php

      參考文檔:

      https://www./manual/zh/function.openssl-encrypt.php

      https://www./manual/zh/function.openssl-decrypt.php

        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多