與對稱加密不一樣的是,非對稱加密和解密使用的是不一樣的密鑰,其中一個對外公開做爲公鑰,另外一個只有全部者擁有,稱爲私鑰。用私鑰加密的信息只有公鑰才能解開,或者反之用弓腰加密的信息只有私鑰才能解開。經常使用的非對稱加密有RSA算法,RSA算法基於一個十分簡單的數論事實:將兩個大質數相乘十分容易,可是想要對其乘積進行因式分解卻極其困難,所以能夠將乘積公開做爲加密密鑰。PHP中提供基於RSA算法的openssl擴展可實現對數據的非對稱加密。php
在RSA加解密以前,須要先生成一對公私鑰,可以使用linux自帶的RSA密鑰生成工具openssl獲取一對公私鑰,也可以使用php openssl擴展函數生成一對公私鑰。使用linux生成一對公私鑰執行如下命令便可:linux
bash-3.2# openssl genrsa -out rsa_private_key.pem 1024android
bash-3.2# openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_key.pemios
bash-3.2# 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 桌面程序等客戶端。bash
筆者生成的一對公私鑰以下:服務器
-----BEGIN PUBLIC KEY-----微信
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+gDNj4Ag6MvL+yfrHdX4qeQFa網絡
J1epFQXBmOsSWBKoXF5haWM6d5gtETO8FRC6RcwpEKZyy7iSyZ70m4EtGMNQvoOT
gHvIceb5GHGBqqMawTjI71P69DYBjWZoLGt/IX3YJixub8nfTG5KW720LXtT/dXn
PAN9jy20h+TfcXvDgwIDAQAB
-----END PUBLIC KEY-----
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQC+gDNj4Ag6MvL+yfrHdX4qeQFaJ1epFQXBmOsSWBKoXF5haWM6
d5gtETO8FRC6RcwpEKZyy7iSyZ70m4EtGMNQvoOTgHvIceb5GHGBqqMawTjI71P6
9DYBjWZoLGt/IX3YJixub8nfTG5KW720LXtT/dXnPAN9jy20h+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——
使用PHP生成公私鑰的代碼以下:
$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
$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
?>
非對稱加密的缺點是加密和解密花費時間長、速度慢,只適合對少許數據進行加密。若是既想有很快的加密速度又想保證數據比對稱加密更加安全,可以使用混合加密,即對數據進行對稱加密,對密鑰作非對稱加密,由於通常祕鑰的長度會小於數據的長度。解密的時候先用非對稱加密獲得密鑰,再用密鑰解開密文獲得明文。
RSA是目前最有影響力的公鑰加密算法,它可以抵抗到目前爲止已知的絕大多數密碼攻擊,已被ISO推薦爲公鑰數據加密標準。
今天只有短的RSA鑰匙纔可能被強力方式解破。到2008年爲止,世界上尚未任何可靠的攻擊RSA算法的方式。只要其鑰匙的長度足夠長,用RSA加密的信息其實是不能被解破的。但在分佈式計算和量子計算機理論日趨成熟的今天,RSA加密安全性受到了挑戰。
本文節選自 《php7實踐指南》 陳小龍著
微信掃一掃,發現更多內容
開啓讚揚