转自:https://www.cnblogs.com/xuweiqiang/p/9784584.html
常用的rsa密钥有两种格式,一种为pkcs1,首尾分别为:
1
2
3
4
5
6
7 1# 公钥
2-----BEGIN RSA PUBLIC KEY-----
3-----END RSA PUBLIC KEY-----
4# 私钥
5-----BEGIN RSA PRIVATE KEY-----
6-----END RSA PRIVATE KEY-----
7
另一种为pkcs8,首尾分别为:
1
2
3
4
5
6
7 1# 公钥
2-----BEGIN PUBLIC KEY-----
3-----END PUBLIC KEY-----
4# 私钥
5-----BEGIN PRIVATE KEY-----
6-----END PRIVATE KEY-----
7
这里加解密: 公钥是私钥转换pkcs8格式后生成(其实用pkcs1生产的公钥也是一样的),私钥还是用的pkcs1格式
具体实现:
1、加密解密的第一步是生成公钥、私钥对,私钥加密的内容能通过公钥解密(反过来亦可以)
1
2 1下载开源RSA密钥生成工具openssl(通常Linux系统都自带该程序),解压缩至独立的文件夹,进入其中的bin目录,执行以下命令:
2
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 1openssl genrsa -out rsa_private_key.pem 1024
2openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_key.pem
3openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
4
5第一条命令生成原始 RSA私钥文件 rsa_private_key.pem
6第二条命令将原始 RSA私钥转换为 pkcs8格式
7第三条生成RSA公钥 rsa_public_key.pem
8
9
10#############常用命令集合
11
12##openssl 生成pkcs1格式的私钥,密钥长度1024位, (PKCS1)
13openssl genrsa -out private_pkcs1.pem 1024
14
15##PKCS1私钥转换为PKCS8
16openssl pkcs8 -topk8 -inform PEM -in private_pkcs1.pem -outform pem -nocrypt -out private_pkcs8.pem
17
18##pkcs8格式私钥转为pkcs1格式私钥:
19openssl rsa -in private_pkcs8.pem -out private_pkcs1_from_pkcs8.pem
20
21##从pkcs1私钥中生成pkcs8公钥
22openssl rsa -in private_pkcs1.pem -pubout -out public_pkcs8.pem
23
24##从pkcs8私钥中生成pkcs8公钥
25openssl rsa -in private_pkcs8.pem -pubout -out public_pkcs8.pem
26
27##pkcs8公钥转pkcs1公钥,这个是打印出来的,需要复制一下放到文件里面(p_pkcs1.pem),空了再找命令
28openssl rsa -pubin -in public_pkcs8.pem -RSAPublicKey_out
29
30##pkcs1公钥转换为pkcs8公钥,这个是打印出来的,需要复制一下放到文件里面,空了再找命令
31openssl rsa -RSAPublicKey_in -in p_pkcs1.pem -pubout
32
33
1
2
3
4 1上面几个就可以看出:通过私钥能生成对应的公钥
2
3也有一些网站提供生成rsa公钥私钥的服务(本人未尝试):http://www.bm8.com.cn/webtool/rsa/
4
2、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 1<?php
2
3
4class Rsa {
5
6 /**
7 * 获取私钥
8 * @return bool|resource
9 */
10 private static function getPrivateKey()
11 {
12 $abs_path = dirname(__FILE__) . '/rsa_private_key.pem';
13 $content = file_get_contents($abs_path);
14 return openssl_pkey_get_private($content);
15 }
16
17 /**
18 * 获取公钥
19 * @return bool|resource
20 */
21 private static function getPublicKey()
22 {
23 $abs_path = dirname(__FILE__) . '/rsa_public_key.pem';
24 $content = file_get_contents($abs_path);
25 return openssl_pkey_get_public($content);
26 }
27
28 /**
29 * 私钥加密
30 * @param string $data
31 * @return null|string
32 */
33 public static function privEncrypt($data = '')
34 {
35 if (!is_string($data)) {
36 return null;
37 }
38 return openssl_private_encrypt($data,$encrypted,self::getPrivateKey()) ? base64_encode($encrypted) : null;
39 }
40
41 /**
42 * 公钥加密
43 * @param string $data
44 * @return null|string
45 */
46 public static function publicEncrypt($data = '')
47 {
48 if (!is_string($data)) {
49 return null;
50 }
51 return openssl_public_encrypt($data,$encrypted,self::getPublicKey()) ? base64_encode($encrypted) : null;
52 }
53
54 /**
55 * 私钥解密
56 * @param string $encrypted
57 * @return null
58 */
59 public static function privDecrypt($encrypted = '')
60 {
61 if (!is_string($encrypted)) {
62 return null;
63 }
64 return (openssl_private_decrypt(base64_decode($encrypted), $decrypted, self::getPrivateKey())) ? $decrypted : null;
65 }
66
67 /**
68 * 公钥解密
69 * @param string $encrypted
70 * @return null
71 */
72 public static function publicDecrypt($encrypted = '')
73 {
74 if (!is_string($encrypted)) {
75 return null;
76 }
77 return (openssl_public_decrypt(base64_decode($encrypted), $decrypted, self::getPublicKey())) ? $decrypted : null;
78 }
79
80}
81
调用demo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 1<?php
2
3require_once "Rsa.php";
4$rsa = new Rsa();
5$data['name'] = 'Tom';
6$data['age'] = '20';
7$privEncrypt = $rsa->privEncrypt(json_encode($data));
8echo '私钥加密后:'.$privEncrypt.'<br>';
9
10$publicDecrypt = $rsa->publicDecrypt($privEncrypt);
11echo '公钥解密后:'.$publicDecrypt.'<br>';
12
13$publicEncrypt = $rsa->publicEncrypt(json_encode($data));
14echo '公钥加密后:'.$publicEncrypt.'<br>';
15
16$privDecrypt = $rsa->privDecrypt($publicEncrypt);
17echo '私钥解密后:'.$privDecrypt.'<br>';
18
代码截图实例:
附,私钥转码为pkcs8 可能会报错:
1
2
3 1unable to load Private Key
2139656125785928:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:703:Expecting: ANY PRIVATE KEY
3
是由于私钥没有换行导致,可以强行进行换行
1
2
3
4
5
6
7
8
9
10
11 1<?php
2$str = "错误私钥";
3$dataArr = str_split($str, 64);
4echo "-----BEGIN RSA PRIVATE KEY-----".PHP_EOL;
5foreach ($dataArr as $trunk) {
6 echo $trunk.PHP_EOL;
7}
8echo "-----END RSA PRIVATE KEY-----".PHP_EOL;
9//执行下命令
10/usr/local/bin/php ./trans.php > test.pem
11
处理完毕之后在执行命令转换格式:
1
2 1openssl pkcs8 -topk8 -inform PEM -in test.pem -outform PEM -nocrypt -out rsa_private_key.pem
2