作者简介:

       姜海强:闷骚码农,互联网行业摸爬滚打数余载,先后担任中国体育直播TV主程、网信集团先锋支付架构师、奇虎360服务器端资深开发。热爱技术,喜欢分享,热衷领域:PHP/Golang语言、面向对象设计模式、Redis、Yaf、Yii2、微服务等。

视频课程

yaf+yar微服务-腾讯课堂
yaf+yar微服务-51CTO学院
CSDN学院

Github

个人主页
swoole-boot
roach
roach-orm

QQ群:

姜海强的QQ群

公众号:

360tryst公众号

openssl

openssl是一个加解密相关的库,这个库在计算机领域得到了广泛的应用。

1.操作系统中安装openssl

安装openssl扩展之前,你的操作系统需要先安装opensslcentos操作系统安装方式

  1. yum install openssl openssl-devel

执行一下命令,如果可以输出版本信息表示安装成功

  1. openssl version -a

作者环境输出

  1. OpenSSL 1.0.2k-fips 26 Jan 2017
  2. built on: reproducible build, date unspecified
  3. platform: linux-x86_64
  4. options: bn(64,64) md2(int) rc4(8x,int) des(idx,cisc,16,int) idea(int) blowfish(idx)
  5. compiler: gcc -I. -I.. -I../include -fPIC -DOPENSSL_PIC -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DKRB5_MIT -m64 -DL_ENDIAN -Wall -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -Wa,--noexecstack -DPURIFY -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DRC4_ASM -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM
  6. OPENSSLDIR: "/etc/pki/tls"
  7. engines: rdrand dynamic

2.安装openssl扩展

在编译安装PHP时,加入--with-openssl[=DIR]参数可以成功安装openssl扩展,如果PHP已经编译安装完成,可以通过phpize方式安装,不过openssl库是一个非常常用的库,建议编译安装PHP环境时将此扩展也一起安装上。具体安装方式可以参考http://404.360tryst.com/views/7.html#layout

3.利用openssl扩展进行加密解密

在介绍加密解密之前,我们先介绍几个名词。

  • 可逆加密

一般加密过程需要使用密钥,输入明文和密钥后经过加密算法得到密文,同样的输出密文和密钥后也能解密出明文,比如常用的AESRSA

  • 非可逆加密

加密过程中不需要使用密钥,输入明文后由系统直接经过加密算法处理成密文,这种加密后的数据是无法被解密的,比如我们前面接触过的md5sha1

  • 对称加密

采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,比如常用的AES加密算法

  • 非对称加密

非对称加密算法需要两个密钥来进行加密和解密,这两个密钥是公开密钥(简称公钥)和私有密钥(简称私钥),比如常用的RSA加密算法

3.1 AES

Advanced Encryption Standard简称AES, 是美国联邦政府采用的一种区块加密标准。

AES加密是通过对称加密实现的,加解密需要一个密钥,密钥长度可以是128位、192位和256位,即16、24和32个字节。

AES常用模式

模式 介绍 优点 缺点
ECB Electronic Code Book,电子密码本模式 有利于并行计算,适合加密小消息 明文进行主动攻击
CBC Cipher Block Chaining,加密区块链模式 不容易主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的标准 不利于并行计算,需要初始化向量IV
CFB Cipher FeedBack Mode,加密反馈模式 分组密码转化为流模式,可以及时加密传送小于分组的数据 不利于并行计算, 唯一的IV
OFB Output FeedBack,输出反馈模式 分组密码转化为流模式,可以及时加密传送小于分组的数据 不利于并行计算, 对明文的主动攻击是可能的

3.1.1 查看PHP环境支持的加密算法模式

  1. <?php
  2. $ciphers = openssl_get_cipher_methods();
  3. var_dump($ciphers);

作者环境输出

  1. array(172) {
  2. [0]=>
  3. string(11) "AES-128-CBC"
  4. [1]=>
  5. string(21) "AES-128-CBC-HMAC-SHA1"
  6. [2]=>
  7. string(11) "AES-128-CFB"
  8. [3]=>
  9. string(12) "AES-128-CFB1"
  10. [4]=>
  11. string(12) "AES-128-CFB8"
  12. [5]=>
  13. string(11) "AES-128-CTR"
  14. [6]=>
  15. string(11) "AES-128-ECB"
  16. [7]=>
  17. string(11) "AES-128-OFB"
  18. [8]=>
  19. string(11) "AES-128-XTS"
  20. [9]=>
  21. string(11) "AES-192-CBC"
  22. [10]=>
  23. string(11) "AES-192-CFB"
  24. [11]=>
  25. string(12) "AES-192-CFB1"
  26. [12]=>
  27. string(12) "AES-192-CFB8"
  28. [13]=>
  29. string(11) "AES-192-CTR"
  30. [14]=>
  31. string(11) "AES-192-ECB"
  32. [15]=>
  33. string(11) "AES-192-OFB"
  34. [16]=>
  35. string(11) "AES-256-CBC"
  36. [17]=>
  37. string(21) "AES-256-CBC-HMAC-SHA1"
  38. [18]=>
  39. string(11) "AES-256-CFB"
  40. [19]=>
  41. string(12) "AES-256-CFB1"
  42. [20]=>
  43. string(12) "AES-256-CFB8"
  44. [21]=>
  45. string(11) "AES-256-CTR"
  46. [22]=>
  47. string(11) "AES-256-ECB"
  48. [23]=>
  49. string(11) "AES-256-OFB"
  50. [24]=>
  51. string(11) "AES-256-XTS"
  52. [25]=>
  53. string(6) "BF-CBC"
  54. [26]=>
  55. string(6) "BF-CFB"
  56. [27]=>
  57. string(6) "BF-ECB"
  58. [28]=>
  59. string(6) "BF-OFB"
  60. [29]=>
  61. string(16) "CAMELLIA-128-CBC"
  62. [30]=>
  63. string(16) "CAMELLIA-128-CFB"
  64. [31]=>
  65. string(17) "CAMELLIA-128-CFB1"
  66. [32]=>
  67. string(17) "CAMELLIA-128-CFB8"
  68. [33]=>
  69. string(16) "CAMELLIA-128-ECB"
  70. [34]=>
  71. string(16) "CAMELLIA-128-OFB"
  72. [35]=>
  73. string(16) "CAMELLIA-192-CBC"
  74. [36]=>
  75. string(16) "CAMELLIA-192-CFB"
  76. [37]=>
  77. string(17) "CAMELLIA-192-CFB1"
  78. [38]=>
  79. string(17) "CAMELLIA-192-CFB8"
  80. [39]=>
  81. string(16) "CAMELLIA-192-ECB"
  82. [40]=>
  83. string(16) "CAMELLIA-192-OFB"
  84. [41]=>
  85. string(16) "CAMELLIA-256-CBC"
  86. [42]=>
  87. string(16) "CAMELLIA-256-CFB"
  88. [43]=>
  89. string(17) "CAMELLIA-256-CFB1"
  90. [44]=>
  91. string(17) "CAMELLIA-256-CFB8"
  92. [45]=>
  93. string(16) "CAMELLIA-256-ECB"
  94. [46]=>
  95. string(16) "CAMELLIA-256-OFB"
  96. [47]=>
  97. string(9) "CAST5-CBC"
  98. [48]=>
  99. string(9) "CAST5-CFB"
  100. [49]=>
  101. string(9) "CAST5-ECB"
  102. [50]=>
  103. string(9) "CAST5-OFB"
  104. [51]=>
  105. string(6) "ChaCha"
  106. [52]=>
  107. string(7) "DES-CBC"
  108. [53]=>
  109. string(7) "DES-CFB"
  110. [54]=>
  111. string(8) "DES-CFB1"
  112. [55]=>
  113. string(8) "DES-CFB8"
  114. [56]=>
  115. string(7) "DES-ECB"
  116. [57]=>
  117. string(7) "DES-EDE"
  118. [58]=>
  119. string(11) "DES-EDE-CBC"
  120. [59]=>
  121. string(11) "DES-EDE-CFB"
  122. [60]=>
  123. string(11) "DES-EDE-OFB"
  124. [61]=>
  125. string(8) "DES-EDE3"
  126. [62]=>
  127. string(12) "DES-EDE3-CBC"
  128. [63]=>
  129. string(12) "DES-EDE3-CFB"
  130. [64]=>
  131. string(13) "DES-EDE3-CFB1"
  132. [65]=>
  133. string(13) "DES-EDE3-CFB8"
  134. [66]=>
  135. string(12) "DES-EDE3-OFB"
  136. [67]=>
  137. string(7) "DES-OFB"
  138. [68]=>
  139. string(8) "DESX-CBC"
  140. [69]=>
  141. string(13) "GOST 28147-89"
  142. [70]=>
  143. string(10) "RC2-40-CBC"
  144. [71]=>
  145. string(10) "RC2-64-CBC"
  146. [72]=>
  147. string(7) "RC2-CBC"
  148. [73]=>
  149. string(7) "RC2-CFB"
  150. [74]=>
  151. string(7) "RC2-ECB"
  152. [75]=>
  153. string(7) "RC2-OFB"
  154. [76]=>
  155. string(3) "RC4"
  156. [77]=>
  157. string(6) "RC4-40"
  158. [78]=>
  159. string(12) "RC4-HMAC-MD5"
  160. [79]=>
  161. string(11) "aes-128-cbc"
  162. [80]=>
  163. string(21) "aes-128-cbc-hmac-sha1"
  164. [81]=>
  165. string(11) "aes-128-ccm"
  166. [82]=>
  167. string(11) "aes-128-cfb"
  168. [83]=>
  169. string(12) "aes-128-cfb1"
  170. [84]=>
  171. string(12) "aes-128-cfb8"
  172. [85]=>
  173. string(11) "aes-128-ctr"
  174. [86]=>
  175. string(11) "aes-128-ecb"
  176. [87]=>
  177. string(11) "aes-128-gcm"
  178. [88]=>
  179. string(11) "aes-128-ofb"
  180. [89]=>
  181. string(11) "aes-128-xts"
  182. [90]=>
  183. string(11) "aes-192-cbc"
  184. [91]=>
  185. string(11) "aes-192-ccm"
  186. [92]=>
  187. string(11) "aes-192-cfb"
  188. [93]=>
  189. string(12) "aes-192-cfb1"
  190. [94]=>
  191. string(12) "aes-192-cfb8"
  192. [95]=>
  193. string(11) "aes-192-ctr"
  194. [96]=>
  195. string(11) "aes-192-ecb"
  196. [97]=>
  197. string(11) "aes-192-gcm"
  198. [98]=>
  199. string(11) "aes-192-ofb"
  200. [99]=>
  201. string(11) "aes-256-cbc"
  202. [100]=>
  203. string(21) "aes-256-cbc-hmac-sha1"
  204. [101]=>
  205. string(11) "aes-256-ccm"
  206. [102]=>
  207. string(11) "aes-256-cfb"
  208. [103]=>
  209. string(12) "aes-256-cfb1"
  210. [104]=>
  211. string(12) "aes-256-cfb8"
  212. [105]=>
  213. string(11) "aes-256-ctr"
  214. [106]=>
  215. string(11) "aes-256-ecb"
  216. [107]=>
  217. string(11) "aes-256-gcm"
  218. [108]=>
  219. string(11) "aes-256-ofb"
  220. [109]=>
  221. string(11) "aes-256-xts"
  222. [110]=>
  223. string(6) "bf-cbc"
  224. [111]=>
  225. string(6) "bf-cfb"
  226. [112]=>
  227. string(6) "bf-ecb"
  228. [113]=>
  229. string(6) "bf-ofb"
  230. [114]=>
  231. string(16) "camellia-128-cbc"
  232. [115]=>
  233. string(16) "camellia-128-cfb"
  234. [116]=>
  235. string(17) "camellia-128-cfb1"
  236. [117]=>
  237. string(17) "camellia-128-cfb8"
  238. [118]=>
  239. string(16) "camellia-128-ecb"
  240. [119]=>
  241. string(16) "camellia-128-ofb"
  242. [120]=>
  243. string(16) "camellia-192-cbc"
  244. [121]=>
  245. string(16) "camellia-192-cfb"
  246. [122]=>
  247. string(17) "camellia-192-cfb1"
  248. [123]=>
  249. string(17) "camellia-192-cfb8"
  250. [124]=>
  251. string(16) "camellia-192-ecb"
  252. [125]=>
  253. string(16) "camellia-192-ofb"
  254. [126]=>
  255. string(16) "camellia-256-cbc"
  256. [127]=>
  257. string(16) "camellia-256-cfb"
  258. [128]=>
  259. string(17) "camellia-256-cfb1"
  260. [129]=>
  261. string(17) "camellia-256-cfb8"
  262. [130]=>
  263. string(16) "camellia-256-ecb"
  264. [131]=>
  265. string(16) "camellia-256-ofb"
  266. [132]=>
  267. string(9) "cast5-cbc"
  268. [133]=>
  269. string(9) "cast5-cfb"
  270. [134]=>
  271. string(9) "cast5-ecb"
  272. [135]=>
  273. string(9) "cast5-ofb"
  274. [136]=>
  275. string(6) "chacha"
  276. [137]=>
  277. string(7) "des-cbc"
  278. [138]=>
  279. string(7) "des-cfb"
  280. [139]=>
  281. string(8) "des-cfb1"
  282. [140]=>
  283. string(8) "des-cfb8"
  284. [141]=>
  285. string(7) "des-ecb"
  286. [142]=>
  287. string(7) "des-ede"
  288. [143]=>
  289. string(11) "des-ede-cbc"
  290. [144]=>
  291. string(11) "des-ede-cfb"
  292. [145]=>
  293. string(11) "des-ede-ofb"
  294. [146]=>
  295. string(8) "des-ede3"
  296. [147]=>
  297. string(12) "des-ede3-cbc"
  298. [148]=>
  299. string(12) "des-ede3-cfb"
  300. [149]=>
  301. string(13) "des-ede3-cfb1"
  302. [150]=>
  303. string(13) "des-ede3-cfb8"
  304. [151]=>
  305. string(12) "des-ede3-ofb"
  306. [152]=>
  307. string(7) "des-ofb"
  308. [153]=>
  309. string(8) "desx-cbc"
  310. [154]=>
  311. string(6) "gost89"
  312. [155]=>
  313. string(10) "gost89-cnt"
  314. [156]=>
  315. string(10) "gost89-ecb"
  316. [157]=>
  317. string(13) "id-aes128-CCM"
  318. [158]=>
  319. string(13) "id-aes128-GCM"
  320. [159]=>
  321. string(13) "id-aes192-CCM"
  322. [160]=>
  323. string(13) "id-aes192-GCM"
  324. [161]=>
  325. string(13) "id-aes256-CCM"
  326. [162]=>
  327. string(13) "id-aes256-GCM"
  328. [163]=>
  329. string(10) "rc2-40-cbc"
  330. [164]=>
  331. string(10) "rc2-64-cbc"
  332. [165]=>
  333. string(7) "rc2-cbc"
  334. [166]=>
  335. string(7) "rc2-cfb"
  336. [167]=>
  337. string(7) "rc2-ecb"
  338. [168]=>
  339. string(7) "rc2-ofb"
  340. [169]=>
  341. string(3) "rc4"
  342. [170]=>
  343. string(6) "rc4-40"
  344. [171]=>
  345. string(12) "rc4-hmac-md5"
  346. }

3.1.2 实现CBC加解密

  1. <?php
  2. //明文
  3. $data = 'jhq';
  4. //加密方法
  5. $method = 'AES-128-CBC';
  6. //密钥
  7. $key = '2jui8ui7jdksd345';
  8. //偏移量
  9. $iv = 'hj89io0765t65678';
  10. $options = OPENSSL_RAW_DATA | OPENSSL_PKCS1_PADDING;
  11. $secretData = openssl_encrypt($data, $method, $key, $options, $iv);
  12. echo '加密结果:'.bin2hex($secretData).PHP_EOL;
  13. $plainData = openssl_decrypt($secretData, $method, $key, $options, $iv);
  14. echo '解密结果:'.$plainData.PHP_EOL;

以上例程运行结果

  1. 加密结果:4da0508f5249ff776be76022d7bd1920
  2. 解密结果:jhq

加密结果返回的是二进制数据,作者将加密结果转换成了16进制字符串。另外给大家推荐一个网址,可以验证自己的加密结果。

http://tool.chacuo.net/cryptaes

注意密钥长度

加密模式 密钥长度
AES-128-* 16字节
AES-192-* 24字节
AES-256-* 32字节

3.2 RSA

Rsa是一种非对称加密算法,加解密需要一对公私钥,私钥有PKCS1(以——-BEGIN RSA PRIVATE KEY——-开头)和PKCS8(以——-BEGIN PRIVATE KEY——-开头)两种格式,另外Rsa除了可以加解密,还可以对数据进行签名。

3.2.1 生成Rsa公私钥

  1. <?php
  2. $keys = openssl_pkey_new([
  3. //长度可以是512,1024,2048
  4. 'private_key_bits' => 2048,
  5. ]);
  6. //生成私钥
  7. openssl_pkey_export($keys, $private_key);
  8. //生成公钥
  9. $public_key = openssl_pkey_get_details($keys)['key'];
  10. var_dump($private_key, $public_key);

以上例程输出

  1. string(1708) "-----BEGIN PRIVATE KEY-----
  2. MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC9v65gAX5L0kDd
  3. 1ULt036CRVp9MprPZ9ltaEsRcd3vR2N2PfZNY0ZmJTwsJVd8230EbL0sYuBpFahq
  4. Xm0zUAQljvT3OjBn2jpYtK0zAvZWFmtvBBaSdiXjnx9S+erQJKBP9LuyITqSlzu0
  5. vjtgRkOxziTqF3WR9GCygALo8hVco/yTjsbSROrz1EYLq0I0GrqNZOGTvNicEPDz
  6. WLMaBPUiWlAce6johEx3uIqJaxnGMXf/6B1Z/CQ7GrC4D0a4otyW+oKLhBdC+U5m
  7. xLiFCqr2BCGi7tt+InnxOMb8wKi1DmheoBfPQS4OI96MPzLvJnx42JsheaJUk6L9
  8. TlkZdLAHAgMBAAECggEBAK+SyqX5G8TKsszQxVJMrTWbOMS563dYj15l73gf1YzP
  9. kJ/ba6ll38EqWQg8MTzN11sdxtloUF/L838hCog9VOjv44lTZXDjA7QK0mxuJEO6
  10. EQSzUrOI8Twyg4iCyZx5F4GEYZzMlGcJ2uw+TbCis4a1yYB13osEBemE+6xSPCPv
  11. 3RIMNNgkpQ/vlPXTvFo62G++GvQjRvVyBYeypfqUKgU9sTT9DuD38724iqxB5NBE
  12. eeIG1CRaEoBakAIqYHWTC/ZpfsoJVF9fdTLU1lWTW1LPkaG7tm7JjnI+Oe898RRG
  13. fK4dfws9hKr3iTZMsGRnbc5uIMf6PYz7/mS/reYmbLkCgYEA4R1m4PCzmCWqGs7F
  14. SvZ2uucTPL6HxOcRA70HW84igxjCwMcYSXyU/usdRVclLFx7zzbzxGTW9VkjTYU5
  15. nQN5t/Bdq81TmhSwYKYoeMtp2h7ieKKOxRVnpzntN29NTJbCiwPQUafzgP3fKIcU
  16. jWi/kp9EWkxhHTdWjVKy9bTHWNMCgYEA18giHn2oc9qAa49m0vk0N5mPHp6p6aLV
  17. mwLSg4vBmWF5PRyH77B21D+GFKHgVclHycdTgDnRChxtJHAMyAGMPf7D9ZEKDMY/
  18. 0xm004Dma+Bthijb1FKVX2NLupblEP2NLlFO4Wi5AFT3ECBAqLy656WYU3/uCCrl
  19. tZODxA81y30CgYEA0oGQBqCPEKOH4fGhBGxcsoIKty7j/vikLH7DNtIX68dntqV2
  20. zKE3IvnxMTpAhK8nB6o3YVt6t4tXO9JtAaqSU7LtpQ4oM1lNZdN63Ro6LcHbvTsl
  21. jp5pgzLj5IasHgaMfTpfvzvytJix6VAHpARjwFQ2ssnhtlRdF2JR/vnBwAkCgYAG
  22. FaagpXpyid7FKa4ElPJb/wCCJIc2B1lunY3CF9bFtHHuvzc2EwvGwGPPgSEKSjqz
  23. /eLk4rx6RILvXBmAKksCFIUCD6zw30Y9daQbsq7Mq+9qsQxB2HJN1kb0Y/zhlcS9
  24. YZ2PzZwp3jt5QO+R0oCSt6Cr+heEM3F2xUoZ5TPnIQKBgQCtVemTHVEavGMs3KNE
  25. N8a4wl7y4z/psv0JhhJ11cWY9NQ7gjQem6+ASv9UYx4B0VVKQ/mtG4Yeq/EJ66ge
  26. 0oFIpHee5rfau5GpSufpu21EG6rGK+yjI9p10iqdJFm4kI88Vp9WXah3eX2apGfP
  27. /ScLgm2Znr5qLCu96ktzGyf8SA==
  28. -----END PRIVATE KEY-----
  29. "
  30. string(451) "-----BEGIN PUBLIC KEY-----
  31. MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvb+uYAF+S9JA3dVC7dN+
  32. gkVafTKaz2fZbWhLEXHd70djdj32TWNGZiU8LCVXfNt9BGy9LGLgaRWoal5tM1AE
  33. JY709zowZ9o6WLStMwL2VhZrbwQWknYl458fUvnq0CSgT/S7siE6kpc7tL47YEZD
  34. sc4k6hd1kfRgsoAC6PIVXKP8k47G0kTq89RGC6tCNBq6jWThk7zYnBDw81izGgT1
  35. IlpQHHuo6IRMd7iKiWsZxjF3/+gdWfwkOxqwuA9GuKLclvqCi4QXQvlOZsS4hQqq
  36. 9gQhou7bfiJ58TjG/MCotQ5oXqAXz0EuDiPejD8y7yZ8eNibIXmiVJOi/U5ZGXSw
  37. BwIDAQAB
  38. -----END PUBLIC KEY-----
  39. "

生成的公私钥可以在这个地址进行校验

http://tool.chacuo.net/cryptrsakeyvalid

Rsa建议采用公钥加密私钥解密私钥签名公钥验签

3.2.2 Rsa加解密实现

  1. <?php
  2. //使用刚刚生成的公私钥
  3. $privateKey = <<<EOL
  4. -----BEGIN PRIVATE KEY-----
  5. MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC9v65gAX5L0kDd
  6. 1ULt036CRVp9MprPZ9ltaEsRcd3vR2N2PfZNY0ZmJTwsJVd8230EbL0sYuBpFahq
  7. Xm0zUAQljvT3OjBn2jpYtK0zAvZWFmtvBBaSdiXjnx9S+erQJKBP9LuyITqSlzu0
  8. vjtgRkOxziTqF3WR9GCygALo8hVco/yTjsbSROrz1EYLq0I0GrqNZOGTvNicEPDz
  9. WLMaBPUiWlAce6johEx3uIqJaxnGMXf/6B1Z/CQ7GrC4D0a4otyW+oKLhBdC+U5m
  10. xLiFCqr2BCGi7tt+InnxOMb8wKi1DmheoBfPQS4OI96MPzLvJnx42JsheaJUk6L9
  11. TlkZdLAHAgMBAAECggEBAK+SyqX5G8TKsszQxVJMrTWbOMS563dYj15l73gf1YzP
  12. kJ/ba6ll38EqWQg8MTzN11sdxtloUF/L838hCog9VOjv44lTZXDjA7QK0mxuJEO6
  13. EQSzUrOI8Twyg4iCyZx5F4GEYZzMlGcJ2uw+TbCis4a1yYB13osEBemE+6xSPCPv
  14. 3RIMNNgkpQ/vlPXTvFo62G++GvQjRvVyBYeypfqUKgU9sTT9DuD38724iqxB5NBE
  15. eeIG1CRaEoBakAIqYHWTC/ZpfsoJVF9fdTLU1lWTW1LPkaG7tm7JjnI+Oe898RRG
  16. fK4dfws9hKr3iTZMsGRnbc5uIMf6PYz7/mS/reYmbLkCgYEA4R1m4PCzmCWqGs7F
  17. SvZ2uucTPL6HxOcRA70HW84igxjCwMcYSXyU/usdRVclLFx7zzbzxGTW9VkjTYU5
  18. nQN5t/Bdq81TmhSwYKYoeMtp2h7ieKKOxRVnpzntN29NTJbCiwPQUafzgP3fKIcU
  19. jWi/kp9EWkxhHTdWjVKy9bTHWNMCgYEA18giHn2oc9qAa49m0vk0N5mPHp6p6aLV
  20. mwLSg4vBmWF5PRyH77B21D+GFKHgVclHycdTgDnRChxtJHAMyAGMPf7D9ZEKDMY/
  21. 0xm004Dma+Bthijb1FKVX2NLupblEP2NLlFO4Wi5AFT3ECBAqLy656WYU3/uCCrl
  22. tZODxA81y30CgYEA0oGQBqCPEKOH4fGhBGxcsoIKty7j/vikLH7DNtIX68dntqV2
  23. zKE3IvnxMTpAhK8nB6o3YVt6t4tXO9JtAaqSU7LtpQ4oM1lNZdN63Ro6LcHbvTsl
  24. jp5pgzLj5IasHgaMfTpfvzvytJix6VAHpARjwFQ2ssnhtlRdF2JR/vnBwAkCgYAG
  25. FaagpXpyid7FKa4ElPJb/wCCJIc2B1lunY3CF9bFtHHuvzc2EwvGwGPPgSEKSjqz
  26. /eLk4rx6RILvXBmAKksCFIUCD6zw30Y9daQbsq7Mq+9qsQxB2HJN1kb0Y/zhlcS9
  27. YZ2PzZwp3jt5QO+R0oCSt6Cr+heEM3F2xUoZ5TPnIQKBgQCtVemTHVEavGMs3KNE
  28. N8a4wl7y4z/psv0JhhJ11cWY9NQ7gjQem6+ASv9UYx4B0VVKQ/mtG4Yeq/EJ66ge
  29. 0oFIpHee5rfau5GpSufpu21EG6rGK+yjI9p10iqdJFm4kI88Vp9WXah3eX2apGfP
  30. /ScLgm2Znr5qLCu96ktzGyf8SA==
  31. -----END PRIVATE KEY-----
  32. EOL;
  33. $publicKey = <<<EOL
  34. -----BEGIN PUBLIC KEY-----
  35. MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvb+uYAF+S9JA3dVC7dN+
  36. gkVafTKaz2fZbWhLEXHd70djdj32TWNGZiU8LCVXfNt9BGy9LGLgaRWoal5tM1AE
  37. JY709zowZ9o6WLStMwL2VhZrbwQWknYl458fUvnq0CSgT/S7siE6kpc7tL47YEZD
  38. sc4k6hd1kfRgsoAC6PIVXKP8k47G0kTq89RGC6tCNBq6jWThk7zYnBDw81izGgT1
  39. IlpQHHuo6IRMd7iKiWsZxjF3/+gdWfwkOxqwuA9GuKLclvqCi4QXQvlOZsS4hQqq
  40. 9gQhou7bfiJ58TjG/MCotQ5oXqAXz0EuDiPejD8y7yZ8eNibIXmiVJOi/U5ZGXSw
  41. BwIDAQAB
  42. -----END PUBLIC KEY-----
  43. EOL;
  44. $data = 'jhq';
  45. //公钥加密
  46. $result = openssl_public_encrypt($data, $secretData, $publicKey);
  47. if(!$result) {
  48. exit('加密失败'.PHP_EOL);
  49. }
  50. echo '加密结果:'.bin2hex($secretData).PHP_EOL;
  51. //私钥解密
  52. $result = openssl_private_decrypt($secretData, $plainData, $privateKey);
  53. if(!$result) {
  54. exit('解密失败'.PHP_EOL);
  55. }
  56. echo '解密结果:'.$plainData.PHP_EOL;

以上例程输出

  1. 加密结果:b4b67a9622b87fc924651f1d52f28be9ddf7182eed1050abd4e92af4ad4d51a11574c400b0898c17744cae9edc34709c215ab137b500c1b2d6b7e3a00829cf24111df381ca778ee308fc6269944fd289d8c36bd5df2e95e526c6c5bffc1647d079844aca94af529eceac66e31f3980e8f87d825ecd09139f43c3b1829d8fb752bcb6554d527c2742611946df9170acf86c0de24d882855db5d735ae2944825ac3db5d25db7686293d6b52eb606eecb453c85552dc19bd317010748a9ec4ab9f382d8d87de387d1fddaad55039ad465be98f6e5b6233f9412dec26abd24ec995bd66dda21321d503ae961ff73bbebb4c38392f828f86a310420b5192fa6d
  2. 解密结果:jhq

注意,Rsa加密是对明文数据长度有限制的,如果需要突破长度限制,另外,运行多次可以发现,尽管解密结果一样,但是每次加密的结果是不一样的。

3.2.3 Rsa数据签名与验签

  1. <?php
  2. //使用刚刚生成的公私钥
  3. $privateKey = <<<EOL
  4. -----BEGIN PRIVATE KEY-----
  5. MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC9v65gAX5L0kDd
  6. 1ULt036CRVp9MprPZ9ltaEsRcd3vR2N2PfZNY0ZmJTwsJVd8230EbL0sYuBpFahq
  7. Xm0zUAQljvT3OjBn2jpYtK0zAvZWFmtvBBaSdiXjnx9S+erQJKBP9LuyITqSlzu0
  8. vjtgRkOxziTqF3WR9GCygALo8hVco/yTjsbSROrz1EYLq0I0GrqNZOGTvNicEPDz
  9. WLMaBPUiWlAce6johEx3uIqJaxnGMXf/6B1Z/CQ7GrC4D0a4otyW+oKLhBdC+U5m
  10. xLiFCqr2BCGi7tt+InnxOMb8wKi1DmheoBfPQS4OI96MPzLvJnx42JsheaJUk6L9
  11. TlkZdLAHAgMBAAECggEBAK+SyqX5G8TKsszQxVJMrTWbOMS563dYj15l73gf1YzP
  12. kJ/ba6ll38EqWQg8MTzN11sdxtloUF/L838hCog9VOjv44lTZXDjA7QK0mxuJEO6
  13. EQSzUrOI8Twyg4iCyZx5F4GEYZzMlGcJ2uw+TbCis4a1yYB13osEBemE+6xSPCPv
  14. 3RIMNNgkpQ/vlPXTvFo62G++GvQjRvVyBYeypfqUKgU9sTT9DuD38724iqxB5NBE
  15. eeIG1CRaEoBakAIqYHWTC/ZpfsoJVF9fdTLU1lWTW1LPkaG7tm7JjnI+Oe898RRG
  16. fK4dfws9hKr3iTZMsGRnbc5uIMf6PYz7/mS/reYmbLkCgYEA4R1m4PCzmCWqGs7F
  17. SvZ2uucTPL6HxOcRA70HW84igxjCwMcYSXyU/usdRVclLFx7zzbzxGTW9VkjTYU5
  18. nQN5t/Bdq81TmhSwYKYoeMtp2h7ieKKOxRVnpzntN29NTJbCiwPQUafzgP3fKIcU
  19. jWi/kp9EWkxhHTdWjVKy9bTHWNMCgYEA18giHn2oc9qAa49m0vk0N5mPHp6p6aLV
  20. mwLSg4vBmWF5PRyH77B21D+GFKHgVclHycdTgDnRChxtJHAMyAGMPf7D9ZEKDMY/
  21. 0xm004Dma+Bthijb1FKVX2NLupblEP2NLlFO4Wi5AFT3ECBAqLy656WYU3/uCCrl
  22. tZODxA81y30CgYEA0oGQBqCPEKOH4fGhBGxcsoIKty7j/vikLH7DNtIX68dntqV2
  23. zKE3IvnxMTpAhK8nB6o3YVt6t4tXO9JtAaqSU7LtpQ4oM1lNZdN63Ro6LcHbvTsl
  24. jp5pgzLj5IasHgaMfTpfvzvytJix6VAHpARjwFQ2ssnhtlRdF2JR/vnBwAkCgYAG
  25. FaagpXpyid7FKa4ElPJb/wCCJIc2B1lunY3CF9bFtHHuvzc2EwvGwGPPgSEKSjqz
  26. /eLk4rx6RILvXBmAKksCFIUCD6zw30Y9daQbsq7Mq+9qsQxB2HJN1kb0Y/zhlcS9
  27. YZ2PzZwp3jt5QO+R0oCSt6Cr+heEM3F2xUoZ5TPnIQKBgQCtVemTHVEavGMs3KNE
  28. N8a4wl7y4z/psv0JhhJ11cWY9NQ7gjQem6+ASv9UYx4B0VVKQ/mtG4Yeq/EJ66ge
  29. 0oFIpHee5rfau5GpSufpu21EG6rGK+yjI9p10iqdJFm4kI88Vp9WXah3eX2apGfP
  30. /ScLgm2Znr5qLCu96ktzGyf8SA==
  31. -----END PRIVATE KEY-----
  32. EOL;
  33. $publicKey = <<<EOL
  34. -----BEGIN PUBLIC KEY-----
  35. MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvb+uYAF+S9JA3dVC7dN+
  36. gkVafTKaz2fZbWhLEXHd70djdj32TWNGZiU8LCVXfNt9BGy9LGLgaRWoal5tM1AE
  37. JY709zowZ9o6WLStMwL2VhZrbwQWknYl458fUvnq0CSgT/S7siE6kpc7tL47YEZD
  38. sc4k6hd1kfRgsoAC6PIVXKP8k47G0kTq89RGC6tCNBq6jWThk7zYnBDw81izGgT1
  39. IlpQHHuo6IRMd7iKiWsZxjF3/+gdWfwkOxqwuA9GuKLclvqCi4QXQvlOZsS4hQqq
  40. 9gQhou7bfiJ58TjG/MCotQ5oXqAXz0EuDiPejD8y7yZ8eNibIXmiVJOi/U5ZGXSw
  41. BwIDAQAB
  42. -----END PUBLIC KEY-----
  43. EOL;
  44. $data = 'jhq';
  45. $key = openssl_get_privatekey($privateKey);
  46. if(!$key) {
  47. exit('私钥解析失败'.PHP_EOL);
  48. }
  49. //私钥签名
  50. $result = openssl_sign($data, $sign, $key);
  51. openssl_free_key($key);
  52. if(!$result) {
  53. exit('签名失败'.PHP_EOL);
  54. }
  55. echo '签名结果:'.bin2hex($sign).PHP_EOL;
  56. $key = openssl_get_publickey($publicKey);
  57. if(!$key) {
  58. exit('公钥解析失败'.PHP_EOL);
  59. }
  60. //公钥验签
  61. $result = openssl_verify($data, $sign, $key);
  62. openssl_free_key($key);
  63. var_dump($result);

以上例程输出

  1. 签名结果:03686621c117275ef847fcabdf57570ceadc818a021832d26c2d112804f56892970b93ba0ffe3354f19079b5904511b9755b4258aec53b5409a6a659424ea6e82c79a21e8341fc7f131c0cb0171f5943626b3d5a754393196cf6445a88afde19e46056f7b864f799e8ecf65c8af66a5236c4231e4bf12e71195e5edff431c98939bc689ac365507b2240725f0f8322c59bcf97ed2a050f6b7bca5265ca1265ca8127885cfe63374085b88274d551bd53303cfff869e1961684e13e439ac3d068ff9cb3b4b6ff5c7817319c13cf5df7bd865c35f7b128072d64e4b20454a72eaaecda1206bba73461ec99f8f19610d72744c64d700d36bac02d04e24746b
  2. int(1)

好了,关于openssl 的介绍就到这里了,大家有兴趣自己可以对加解密、数据签名做一下简单的封装。

QQ群:

姜海强的QQ群

公众号:

360tryst公众号