使用phpopenssl擴充套件實現非對稱加密

技術小牛人發表於2017-11-07

php的openssl擴充套件可對資料進行簽名,也可對資料進行非對稱加密。非對稱加密使用私鑰加密,公鑰解密。

這裡介紹openssl實現非對稱加密

可使用linux自帶的RSA金鑰生成工具openssl,獲取一對公私鑰,也可使用php openssl擴充套件函式生成一對公私鑰

先說第一種:

執行以下命令:

openssl genrsa -out rsa_private_key.pem 1024

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

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

從上面看出通過私鑰能生成對應的公鑰,因此我們將私鑰private_key.pem用在伺服器端,公鑰發放給android ios 桌面程式等客戶端

筆者生成的一對公私鑰如下:

—–BEGIN PUBLIC KEY—–

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+gDNj4Ag6MvL+yfrHdX4qeQFa

J1epFQXBmOsSWBKoXF5haWM6d5gtETO8FRC6RcwpEKZyy7iSyZ70m4EtGMNQvoOT

gHvIceb5GHGBqqMawTjI71P69DYBjWZoLGt/IX3YJixub8nfTG5KW720LXtT/dXn

PAN9jy21h+TfcXvDgwIDAQAB

—–END PUBLIC KEY—–


—–BEGIN RSA PRIVATE KEY—–

MIICXAIBAAKBgQC+gDNj4Ag6MvL+yfrHdX4qeQFaJ1epFQXBmOsSWBKoXF5haWM6

d5gtETO8FRC6RcwpEKZyy7iSyZ70m4EtGMNQvoOTgHvIceb5GHGBqqMawTjI71P6

9DYBjWZoLGt/IX3YJixub8nfTG5KW720LXtT/dXnPAN9jy21h+TfcXvDgwIDAQAB

AoGAEkfZJp9sCrGy8dJOF2/l8It2HsGhvt7+k2pqPHNpLvDWOcDUPdsWJlT9QvI+

jbF++v3XCzMTfjqM32pAxiQXMfEDcF26wkZtB8E+QVtV0rR9I1OP0wTtfw1tWkd5

cEgfoIrEhaADrxDtLOSDJfDKTKB72H98Lu3iV2iF6igFnQECQQDfLv6eFbH1wmn1

yGq3mR5z1f2yGdSngcgcC53qW8gl6GjjXlyzepz3o+wQ2fk1sLQ+xVGRy7UQHszl

PIDIVaaBAkEA2oL4kQW8jtB+b086ItINyw08x8jCf6Wcmw/SUytdNAGFy8csifwD

FweY9mxH0Cy/ynF3NA+2LQZO0Bz2/DLQAwJAI1lCIq+0/APK3I7duC6cUCR4hhjp

QY6grzB31oKq9LYWxsxPSm4FJoPkA9dCTWqrYbXG8ZyeFOuL8FLg4toOAQJBAIjE

iUhcStUo8rpA4KaCy1dYhb6WjgbPZeI4WPDtp3yxp0kQ9XO4ZUa43qj+xUQrfi/8

LRxM6T3tQM9KEd1xAHkCQGR8bklYgPvgT6Aep/Nq7NZq24N3NC7FY8YxZ85rKpTl

Tnm0UJ8WBNg43uztQ4MJ1IFSwVEOlUVm5VYvV+IIunM=

—–END RSA PRIVATE KEY—–


示例程式碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php
/**
 * Created by PhpStorm.
 * User: chenxiaolong
 * Date: 2016/9/10
 * Time: 16:31
 */
 
$private_key_path `rsa_private_key.pem`;
$public_key_path `rsa_public_key.pem`;
$private_key file_get_contents($private_key_path);
$public_key file_get_contents($public_key_path);
//這個函式可用來判斷私鑰是否是可用的,可用返回資源id Resource id,不可用返回false
$pi_key =  openssl_pkey_get_private($private_key);
//這個函式可用來判斷公鑰是否是可用的,同上
$pu_key = openssl_pkey_get_public($public_key);
$data "hello";//原始資料
$encrypted "";
$decrypted "";
 
//私鑰加密,也可使用openssl_public_encrypt公鑰加密,然後使用openssl_private_decrypt解密,加密後資料在$encrypted
openssl_private_encrypt($data,$encrypted,$pi_key);
//加密後的內容通常含有特殊字元,需要編碼轉換下,在網路間通過url傳輸時要注意base64編碼是否是url安全的
$encrypted base64_encode($encrypted);
//私鑰加密的內容通過公鑰可解密出來,公鑰加密的可用私鑰解密。不能混淆
openssl_public_decrypt(base64_decode($encrypted),$decrypted,$pu_key);
echo $decrypted// hello
 
 
//私鑰加密
openssl_private_encrypt($data,$encrypted,$pi_key);
$encrypted base64_encode($encrypted);
//公鑰解密
openssl_public_decrypt(base64_decode($encrypted),$decrypted,$pu_key);
echo $decrypted//hello


使用PHP自己也可生成一對公私鑰。程式碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$config array(
    "digest_alg" => "sha512",
    "private_key_bits" => 4096,
    "private_key_type" => OPENSSL_KEYTYPE_RSA,
);
// 建立公私鑰
$res = openssl_pkey_new($config);
// 獲得私鑰 $privKey
openssl_pkey_export($res$privKey);
// 獲得公鑰 $pubKey
$pubKey = openssl_pkey_get_details($res);
$pubKey $pubKey["key"];
$data `hello`;
// 私鑰加密
openssl_private_encrypt($data$encrypted ,$privKey);
// 公鑰解密
openssl_public_decrypt($encrypted$decrypted$pubKey);
echo $decrypted;

兩種方式沒有本質區別,只是生成公私鑰的方式不同。


非對稱加密的缺點是加密和解密花費時間長、速度慢,只適合對少量資料進行加密。如果既想有很快的加密速度又想保證資料比對稱加密更加安全,可對資料進行對稱加密,對祕鑰做非對稱加密,因為一般祕鑰的長度會小於資料的長度。


php openssl還可實現數字簽名。關於openssl實現數字簽名的內容請檢視php.net官方網址。



參考博文:

數字簽名 http://www.ruanyifeng.com/blog/2011/08/what_is_a_digital_signature.html

非對稱加密 http://www.cnblogs.com/jfzhu/p/4020928.html

本文轉自  陳小龍哈   51CTO部落格,原文連結:http://blog.51cto.com/chenxiaolong/1851466


相關文章