php-rsa 加密解密

1.什麼是RSA加密

RSA (詳見維基百科)算法是現今使用最普遍的公鑰密碼算法,也是號稱地球上最安全的加密算法,與 md5sha1 不一樣,到目前爲止,也只有極短的RSA加密被破解。
那麼什麼是公匙密碼算法呢,根據密鑰的使用方法,能夠將密碼分爲對稱密碼和公鑰密碼,接下來咱們來簡單說明下它們兩個。
對稱密碼:加密和解密使用同一種密鑰的方式,經常使用的算法有 DES 以及 AES
公鑰密碼:加密和解密使用不一樣的密碼的方式,所以公鑰密碼一般也稱爲非對稱密碼,經常使用的算法有 RSAphp

因爲本文討論的是 phpRSA 加密實例,這裏就不詳細說明了,對於 RSA 算法有興趣的朋友能夠查看下面的文章
《帶你完全理解RSA算法原理》
對於 php 更多加密方式有興趣的朋友能夠查看下面的文章
《PHP數據加密技術與密鑰安全管理》linux

2.使用場景

  • 爲移動端(IOS,安卓)編寫 API 接口算法

  • 進行支付、真實信息驗證等安全性需求較高的通訊ubuntu

  • 與其餘第三方或合做夥伴進行重要的數據傳輸segmentfault

3.生成私鑰、公鑰

既然 RSA 是非對稱加密,那麼就先必須生成所須要的私鑰和公鑰,以 ubuntu 爲例。首先下載開源 RSA 密鑰生成工具 openssl (一般爲 linux 系統自帶),若是沒有,能夠經過如下命令進行安裝安全

apt-get install openssl

openssl 安裝完畢後,咱們就能夠開始生成私鑰、公鑰了。首先,生成原始 RSA 私鑰文件服務器

openssl genrsa -out rsa_private_key.pem 1024

注:這裏生成了一個長度爲 1024bit 的密鑰,轉化爲字節就是 128bytephp7

其次,將原始 RSA 私鑰轉換爲 pkcs8 格式less

openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_key.pem

最後,生成 RSA 公鑰函數

openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

在須要使用的時候,咱們將私鑰 rsa_private_key.pem 放在服務器端,公鑰發放給須要與咱們進行加密通訊的一方就能夠了。

4.php-rsa 加密解密實例

如今咱們可使用 php 進行 RSA 的加密解密了,但在此以前,你首先要看看你有沒有安裝或開啓 phpopenssl 擴展,能夠經過文件輸出 phpinfo() 或者經過命令行輸出 php -m | less 來查看是否安裝開啓了此擴展,也能夠經過 extension_loaded() 函數來判斷擴展是否開啓,若是沒有,則經過該命令進行安裝(以 ubuntu 爲例):

apt-get install php7.0-openssl

固然,若是你是 Windows 操做系統,能夠下載對應版本的 php_openssl.dll

好了,如今咱們來編寫一個 php-RSA 的服務器類庫,這個類庫的工做其實很簡單,就是封裝一些 php 針對 RSA 操做的函數,方便咱們加密解密。

class Rsa
{
    private $_config = [
        'public_key' => '',
        'private_key' => '',
    ];

    public function __construct($private_key_filepath, $public_key_filepath) {
        $this->_config['private_key'] = $this->_getContents($private_key_filepath);
        $this->_config['public_key'] = $this->_getContents($public_key_filepath);
    }

    /**
     * @uses 獲取文件內容
     * @param $file_path string
     * @return bool|string
     */
    private function _getContents($file_path) {
        file_exists($file_path) or die ('密鑰或公鑰的文件路徑錯誤');
        return file_get_contents($file_path);
    }

    /**     
     * @uses 獲取私鑰
     * @return bool|resource     
     */ 
    private function _getPrivateKey() {
       $priv_key = $this->_config['private_key'];
       return openssl_pkey_get_private($priv_key);
    }

    /**     
     * @uses 獲取公鑰
     * @return bool|resource     
     */    
    private function _getPublicKey() {        
        $public_key = $this->_config['public_key'];
        return openssl_pkey_get_public($public_key);
    }

    /**     
     * @uses 私鑰加密
     * @param string $data     
     * @return null|string     
     */    
    public function privEncrypt($data = '') {        
        if (!is_string($data)) {
            return null;       
        }
        return openssl_private_encrypt($data, $encrypted, $this->_getPrivateKey()) ? base64_encode($encrypted) : null;
    }

    /**     
     * @uses 公鑰加密     
     * @param string $data     
     * @return null|string     
     */    
    public function publicEncrypt($data = '') {        
        if (!is_string($data)) {
            return null;        
        }        
        return openssl_public_encrypt($data, $encrypted, $this->_getPublicKey()) ? base64_encode($encrypted) : null;
    }

    /**     
     * @uses 私鑰解密     
     * @param string $encrypted     
     * @return null     
     */    
    public function privDecrypt($encrypted = '') {        
        if (!is_string($encrypted)) {
            return null;        
        }
        return (openssl_private_decrypt(base64_decode($encrypted), $decrypted, $this->_getPrivateKey())) ? $decrypted : null;
    }    

    /**     
     * @uses 公鑰解密     
     * @param string $encrypted     
     * @return null     
     */    
    public function publicDecrypt($encrypted = '') {        
        if (!is_string($encrypted)) {
            return null;        
        }        
           return (openssl_public_decrypt(base64_decode($encrypted), $decrypted, $this->_getPublicKey())) ? $decrypted : null;
    }
}

好了,如今咱們調用 Rsa 類,對數據進行加密解密

$private_key = 'private_key.pem'; // 私鑰路徑
$public_key = 'rsa_public_key.pem'; // 公鑰路徑
$rsa = new Rsa($private_key, $public_key);

$origin_data = '這是一條測試數據';

$ecryption_data = $rsa->privEncrypt($origin_data);

$decryption_data = $rsa->publicDecrypt($ecryption_data);

echo '私鑰加密後的數據爲:' . $ecryption_data;
echo PHP_EOL;
echo '公鑰解密後的數據爲: ' . $decryption_data;
echo PHP_EOL;

最後咱們看到輸出:

圖片描述

最後要說明的是,公鑰、私鑰均可以加密,也均可以解密。其中:用公鑰加密須要私鑰解密,稱爲「加密」。因爲私鑰是不公開的,確保了內容的保密,沒有私鑰沒法得到內容;用私鑰加密須要公鑰解密,稱爲「簽名」。因爲公鑰是公開的,任何人均可以解密內容,但只能用發佈者的公鑰解密,驗證了內容是該發佈者發出的。

相關文章
相關標籤/搜索