2017年10月31日 星期二

[php] php 怎麼使用 RSA 非對稱式加密



首先,要先產生 RSA 公私鑰,我們使用公鑰放在client 端,然後,在server 端使用 private key 來解密。

先產生私鑰
  openssl genrsa -out private_pg_report.key 1024
再用私鑰生成公鑰
  openssl rsa -in private_pg_report.key -out public_pg_report.pem -outform PEM -pubout

放置下面兩個路徑 REPORT_PUBLIC_KEY_PATH , REPORT_PRIVATE_KEY_PATH
這邊要注意的是,RSA 只能加密117 位,所以 使用str_split 去分隔成chunk ,分段加密,最後再使用 base64_encode 成 string 。
解密是反過來的過程,加密後的長度就是固定128。所以使用 128 去做str_split 。


    public function encrypt($plain)
    {
        $fp = fopen(REPORT_PUBLIC_KEY_PATH, "r");
        $pubKey = fread($fp, 8192);
        fclose($fp);
        $pubKeyRes = openssl_get_publickey($pubKey);
        if (!$pubKeyRes) {
            throw new Exception('Public Key invalid');
        }
        $finalCrypt = '';
        foreach (str_split($plain, 117) as $chunk) {
            if (openssl_public_encrypt($chunk, $crypt, $pubKeyRes)) {
                $finalCrypt .= $crypt;
            }
        }
        openssl_free_key($pubKeyRes);
        return base64_encode($finalCrypt);
    }

    public function decrypt($encrypted)
    {
        $fp = fopen(REPORT_PRIVATE_KEY_PATH, "r");
        $privateKey = fread($fp, 8192);
        fclose($fp);
        $privateKeyRes = openssl_get_privatekey($privateKey);
        if (!$privateKeyRes) {
            throw new Exception('Private Key invalid');
        }
        $finalDecrypted = '';
        foreach (str_split(base64_decode($encrypted), 128) as $chunk) {
            openssl_private_decrypt($chunk, $decrypted, $privateKeyRes);
            $finalDecrypted .= $decrypted;
        }
        openssl_free_key($privateKeyRes);
        return $finalDecrypted;
    }

PHP 使用 RSA 公钥对 JSON 对象进行加密,加密不了? - V2EX
https://www.v2ex.com/t/327672
PHP加密的几种方式 - 简书
http://www.jianshu.com/p/5f42699d8af5


沒有留言:

張貼留言