1. 程式人生 > 實用技巧 >PHP 使用非對稱加密演算法

PHP 使用非對稱加密演算法

加密的型別:

在日常設計及開發中,為確保資料傳輸和資料儲存的安全,可通過特定的演算法,將資料明文加密成複雜的密文。目前主流加密手段大致可分為單向加密和雙向加密。

單向加密:通過對資料進行摘要計算生成密文,密文不可逆推還原。演算法代表:Base64,MD5,SHA; 

雙向加密:與單向加密相反,可以把密文逆推還原成明文,雙向加密又分為對稱加密和非對稱加密。

對稱加密:指資料使用者必須擁有相同的金鑰才可以進行加密解密,就像彼此約定的一串暗號。演算法代表:DES,3DES,AES,IDEA,RC4,RC5;

非對稱加密:相對對稱加密而言,無需擁有同一組金鑰,非對稱加密是一種“資訊公開的金鑰交換協議”。非對稱加密需要公開金鑰和私有金鑰兩組金鑰,公開金鑰和私有金鑰是配對起來的,也就是說使用公開金鑰進行資料加密,只有對應的私有金鑰才能解密。這兩個金鑰是數學相關,用某使用者金鑰加密後的密文,只能使用該使用者的加密金鑰才能解密。如果知道了其中一個,並不能計算出另外一個。因此如果公開了一對金鑰中的一個,並不會危害到另外一個金鑰性質。這裡把公開的金鑰為公鑰,不公開的金鑰為私鑰。演算法代表:RSA,DSA。

以前一直對客戶端傳給伺服器的資訊加密這一塊一臉懵,如果app裡面的使用者登入資訊被抓包拿到了,大寫著 username:root,password:123456,那不是很尷尬。

偶然做版權輸入的時候遇到了rsa,在支付寶支付的時候也接觸過,當時不知道這是啥子,現在才知道。

他能保證,客戶端給出的資訊,只有擁有私鑰的伺服器才能看,其他人看的都是亂碼,嘿嘿。

非對稱加密演算法
需要兩個金鑰:公開金鑰(publickey)和私有金鑰(privatekey)。
公開金鑰與私有金鑰是一對,如果用公開金鑰對資料進行加密,只有用對應的私有金鑰才能解密;
如果用私有金鑰對資料進行加密,那麼只有用對應的公開金鑰才能解密。
因為加密和解密使用的是兩個不同的金鑰,所以這種演算法叫作非對稱加密演算法。

注意以上的一個點,公鑰加密的資料,只有對應的私鑰才能解密

在日常使用中是醬紫的:
將私鑰private_key.pem用在伺服器端,公鑰發放給android跟ios等前端

  

客戶端用公鑰加密過後,資料只能被擁有唯一私鑰的伺服器看懂。

具體實現:

1、加密解密的第一步是生成公鑰、私鑰對,私鑰加密的內容能通過公鑰解密(反過來亦可以)

下載開源RSA金鑰生成工具openssl(通常Linux系統都自帶該程式),解壓縮至獨立的資料夾,進入其中的bin目錄,執行以下命令:
a、openssl genrsa -out rsa_private_key.pem 1024
b、openssl pkcs8 
-topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_key.pem c、openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem 第一條命令生成原始 RSA私鑰檔案 rsa_private_key.pem 第二條命令將原始 RSA私鑰轉換為 pkcs8格式 第三條生成RSA公鑰 rsa_public_key.pem 上面幾個就可以看出:通過私鑰能生成對應的公鑰

也有一些網站提供生成rsa公鑰私鑰的服務:http://www.bm8.com.cn/webtool/rsa/

2、PHP的加密解密類庫:

<?php


class Rsa {
 
    /**     
     * 獲取私鑰     
     * @return bool|resource     
     */    
    private static function getPrivateKey() 
    {        
        $abs_path = dirname(__FILE__) . '/rsa_private_key.pem';
        $content = file_get_contents($abs_path);    
        return openssl_pkey_get_private($content);    
    }    

    /**     
     * 獲取公鑰     
     * @return bool|resource     
     */    
    private static function getPublicKey()
    {   
        $abs_path = dirname(__FILE__) . '/rsa_public_key.pem';
        $content = file_get_contents($abs_path);    
        return openssl_pkey_get_public($content);     
    }

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

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

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

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

}

呼叫demo:

<?php

require_once "Rsa.php";
$rsa = new Rsa();
$data['name'] = 'Tom';
$data['age']  = '20';
$privEncrypt = $rsa->privEncrypt(json_encode($data));
echo '私鑰加密後:'.$privEncrypt.'<br>';

$publicDecrypt = $rsa->publicDecrypt($privEncrypt);
echo '公鑰解密後:'.$publicDecrypt.'<br>';

$publicEncrypt = $rsa->publicEncrypt(json_encode($data));
echo '公鑰加密後:'.$publicEncrypt.'<br>';

$privDecrypt = $rsa->privDecrypt($publicEncrypt);
echo '私鑰解密後:'.$privDecrypt.'<br>';

來源:https://www.cnblogs.com/xuweiqiang/p/9784584.html