forked from china8036/RSA
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRsa.php
executable file
·149 lines (133 loc) · 4.81 KB
/
Rsa.php
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
<?php
/**
* RSA 公钥 私钥加密 解密 尝试
* @author wang <baobeigou.com>
*/
class Rsa {
private $_config;
function __construct() {
$rsa_config = array();
require_once ('rsa.config.php');//配置文件
if (empty($rsa_config['private_key']) && empty($rsa_config['public_key'])) {
throw new Exception('请配置公钥或私钥参数');
}
$this->_config = $rsa_config;
}
/**
* 私钥加密
* @param string $data 要加密的数据
* @return string 加密后的字符串
*/
public function privateKeyEncode($data) {
$encrypted = '';
$this->_needKey(2);
$private_key = openssl_pkey_get_private($this->_config['private_key']);
$fstr = array();
$array_data = $this->_splitEncode($data);//把要加密的信息 base64 encode后 等长放入数组
foreach ($array_data as $value) {//理论上是可以只加密数组中的第一个元素 其他的不加密 因为只要一个解密不出来 整体也就解密不出来 这里先全部加密
openssl_private_encrypt($value, $encrypted, $private_key); //私钥加密
$fstr[] = $encrypted;//对数组中每个加密
}
return base64_encode(serialize($fstr));//序列化后base64_encode
}
/**
* 公钥加密
* @param string $data 要加密的数据
* @return string 加密后的字符串
*/
public function publicKeyEncode($data) {
$encrypted = '';
$this->_needKey(1);
$public_key = openssl_pkey_get_public($this->_config['public_key']);
$fstr = array();
$array_data = $this->_splitEncode($data);
foreach ($array_data as $value) {
openssl_public_encrypt($value, $encrypted, $public_key); //私钥加密
$fstr[] = $encrypted;
}
return base64_encode(serialize($fstr));
}
/**
* 用公钥解密私钥加密内容
* @param string $data 要解密的数据
* @return string 解密后的字符串
*/
public function decodePrivateEncode($data) {
$decrypted = '';
$this->_needKey(1);
$public_key = openssl_pkey_get_public($this->_config['public_key']);
$array_data = $this->_toArray($data);//数据base64_decode 后 反序列化成数组
$str = '';
foreach ($array_data as $value){
openssl_public_decrypt($value, $decrypted, $public_key); //私钥加密的内容通过公钥可用解密出来
$str .= $decrypted;//对数组中的每个元素解密 并拼接
}
return base64_decode($str);//把拼接的数据base64_decode 解密还原
}
/**
* 用私钥解密公钥加密内容
* @param string $data 要解密的数据
* @return string 解密后的字符串
*/
public function decodePublicEncode($data) {
$decrypted = '';
$this->_needKey(2);
$private_key = openssl_pkey_get_private($this->_config['private_key']);
$array_data = $this->_toArray($data);
$str = '';
foreach ($array_data as $value){
openssl_private_decrypt($value, $decrypted, $private_key); //私钥解密
$str .= $decrypted;
}
return base64_decode($str);
}
/**
* 检查是否 含有所需配置文件
* @param int 1 公钥 2 私钥
* @return int 1
* @throws Exception
*/
private function _needKey($type) {
switch ($type) {
case 1:
if (empty($this->_config['public_key'])) {
throw new Exception('请配置公钥');
}
break;
case 2:
if (empty($this->_config['private_key'])) {
throw new Exception('请配置私钥');
}
break;
}
return 1;
}
/**
*
* @param type $data
* @return type
*/
private function _splitEncode($data) {
$data = base64_encode($data); //加上base_64 encode 便于用于 分组
$total_lenth = strlen($data);
$per = 96;// 能整除2 和 3 RSA每次加密不能超过100个
$dy = $total_lenth % $per;
$total_block = $dy ? ($total_lenth / $per) : ($total_lenth / $per - 1);
for ($i = 0; $i < $total_block; $i++) {
$return[] = substr($data, $i * $per, $per);//把要加密的信息base64 后 按64长分组
}
return $return;
}
/**
*公钥加密并用 base64 serialize 过的 data
* @param type $data base64 serialize 过的 data
*/
private function _toArray($data){
$data = base64_decode($data);
$array_data = unserialize($data);
if(!is_array($array_data)){
throw new Exception('数据加密不符');
}
return $array_data;
}
}