1. 程式人生 > >windows環境下php配置openssl的openssl.cnf

windows環境下php配置openssl的openssl.cnf

 

說明:

php服務端與客戶端互動、提供開放api時,通常需要對敏感的部分api資料傳輸進行資料加密,這時候rsa非對稱加密就能派上用處了,下面通過一個例子來說明如何用php來實現資料的加密解密

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

通過私鑰能生成對應的公鑰,因此我們將私鑰用在伺服器端,公鑰發放給android、ios等前端

 

配置:

 

開啟OpenSSL擴充套件

下載對應php版本檔案:https://windows.php.net/downloads/php-sdk/deps/

解壓到對應php版本目錄下:D:\phpStudy\php\php-5.3.29-nts\extras

生成公鑰私鑰

 

$config = array(
   'config' => 'D:\phpStudy\php\php-5.3.29-nts\extras\openssl\openssl.cnf',
   'digest_alg' => 'sha512',
   'private_key_bits' => 512,                     //位元組數    512 1024  2048   4096 等
   'private_key_type' => OPENSSL_KEYTYPE_RSA,     //加密型別
);

//建立公鑰和私鑰   返回資源
$res = openssl_pkey_new($config);

//從得到的資源中獲取私鑰    並把私鑰賦給
openssl_pkey_export($res, $privKey, null, $config);

//從得到的資源中獲取公鑰    返回公鑰
$pubKey = openssl_pkey_get_details($res);

$pubKey = $pubKey["key"];

echo '<pre>';
var_dump(array('privKey' => $privKey, 'pubKey' => $pubKey));
使用示例:

 

//私匙
         $private_key = '-----BEGIN RSA PRIVATE KEY-----
MIIBOgIBAAJBAJmIHQFP5yh8ztq7+vvkdDCGBqTxymVpDDsmrVeGhLqse7NKXS2H
+zzbwXbe19wueQJ90QpElUpUviCg3WhdxMECAwEAAQJAWeXPRgNpUNWzsXQ8g93D
At6XaWGCp1qZJNGC0isb8MlCAHgt+G/y4yMtEmNio/IftpK1qI5SM6ODBcqsEHUB
IQIhAMeJPTB/7pYyx+ShMYQCOLBHM708ANqIPsFnAR1KvY6tAiEAxPo7MH1roobv
Xq9898slHJxD+nXKnaU3BLwzfc9aNOUCIC6HL/+JNWdMvBPyCovPwMxKLiRoQ4Kx
1oBetoHQFdeZAiEAnntaTgxLIowAYaU+HbyTkm5j/0rwh2AbYTLvFuVTBcUCIBj7
oq98J0h9cmd5c9dqLisaKbWZETgWextIAmi0FcyE
-----END RSA PRIVATE KEY-----';

//公匙
         $public_key = '-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJmIHQFP5yh8ztq7+vvkdDCGBqTxymVp
DDsmrVeGhLqse7NKXS2H+zzbwXbe19wueQJ90QpElUpUviCg3WhdxMECAwEAAQ==
-----END PUBLIC KEY-----';

         $data = json_encode(array('name' => '張三', 'age' => 18));//原始資料  或者是需要加密的資料

         $pi_key = openssl_pkey_get_private($private_key);//這個函式可用來判斷私鑰是否是可用的,可用返回資源id Resource id
         $pu_key = openssl_pkey_get_public($public_key);//這個函式可用來判斷公鑰是否是可用的


         //私匙加密公鑰解密
         openssl_private_encrypt($data, $encrypted, $pi_key);//私鑰加密
         $encrypted = base64_encode($encrypted);//base64只是為了避免特殊字元
         var_dump('私鑰加密之後的結果:<br>' . $encrypted);echo '<br>';

         openssl_public_decrypt(base64_decode($encrypted), $decrypted, $pu_key);//私鑰加密的內容通過公鑰可用解密出來
         var_dump(json_decode($decrypted, true));echo '<br>';

         //公鑰加密私鑰解密
         openssl_public_encrypt($data, $encrypted, $pu_key);//公鑰加密
         $encrypted = base64_encode($encrypted);  //base64只是為了避免特殊字元
         var_dump('公鑰加密之後的結果:<br>' . $encrypted);echo '<br>';
         openssl_private_decrypt(base64_decode($encrypted), $decrypted, $pi_key);//私鑰解密
         var_dump(json_decode($decrypted, true));echo '<br>';
對於字串超長的加密,需要另外封裝:

 

/**
 * RSA公鑰加密
 * @param $originalStr
 * @return string
 */
   function rsaEncrypt($originalStr){

    $str = base64_encode($originalStr);

    $crypto = '';
    $pub_key = openssl_pkey_get_public(RSA_public_key);

    foreach (str_split($str, 117) as $chunk) {

       openssl_public_encrypt($chunk, $encryptData, $pub_key);

       $crypto .= $encryptData;
    }

    return $crypto;

   }


/**
 * RSA私鑰解密
 * @param $encryptStr
 * @return bool|string
 */
function rsaDecrypt($encryptStr){

   $crypto = '';
   $pri_key = openssl_pkey_get_private(RSA_private_key);
   foreach (str_split($encryptStr, 128) as $chunk) {

      openssl_private_decrypt($chunk, $decryptData, $pri_key);

      $crypto .= $decryptData;
   }

   return base64_decode($crypto);
}