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