Ssl.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. <?php namespace Api\Lib\Platform;
  2. use Dever;
  3. class Ssl
  4. {
  5. public function init($field)
  6. {
  7. $this->field = $field;
  8. return $this;
  9. }
  10. public function encrypt($id, $value)
  11. {
  12. $config = $this->config($id, 1, $value);
  13. if ($config) {
  14. if ($config['type'] == 1) {
  15. # 非对称
  16. openssl_public_encrypt($config['value'], $value, $config['cert'], $config['option']);
  17. } elseif ($config['type'] == 2 && $config['cipher_algo']) {
  18. # 对称
  19. $value = openssl_encrypt($config['value'], $config['cipher_algo'], $config['cert'], $config['option'], $config['iv'], $config['tag'], $config['aad'], $config['tag_len']);
  20. } elseif ($config['type'] == 3 && $config['cipher_algo']) {
  21. # 签名
  22. openssl_sign($config['value'], $value, $config['cert'], $config['cipher_algo']);
  23. }
  24. if ($config['after'] == 2) {
  25. $value = base64_encode($value);
  26. }
  27. }
  28. return $value;
  29. }
  30. public function decrypt($id, $value, $data = '')
  31. {
  32. if (is_array($value)) {
  33. $value = Dever::json_encode($value);
  34. }
  35. $config = $this->config($id, 2, $value);
  36. if ($config) {
  37. if ($config['type'] == 1) {
  38. # 非对称
  39. openssl_public_decrypt($config['value'], $value, $config['cert'], $config['option']);
  40. } elseif ($config['type'] == 2 && $config['cipher_algo']) {
  41. # 对称
  42. $value = openssl_decrypt($config['value'], $config['cipher_algo'], $config['cert'], $config['option'], $config['iv'], $config['tag'], $config['aad']);
  43. } elseif ($config['type'] == 3 && $config['cipher_algo']) {
  44. # 签名验证
  45. $value = openssl_verify($data, $config['value'], $config['cert'], $config['cipher_algo']);
  46. }
  47. }
  48. return $value;
  49. }
  50. protected function config($id, $type, $value)
  51. {
  52. $config = Dever::db('api/platform_ssl')->find($id);
  53. if (!$config) {
  54. return false;
  55. }
  56. $config['value'] = $value;
  57. $key = $type == 1 ? 'encrypt' : 'decrypt';
  58. $this->cert($config, $key);
  59. if (!$config['cert']) {
  60. return false;
  61. }
  62. if ($type == 2 && $config['after'] == 2) {
  63. $config['value'] = base64_decode($config['value']);
  64. }
  65. # 对称加密需要特殊处理一下
  66. if ($config['type'] == 2) {
  67. if (!$config['option']) {
  68. $config['option'] = 'OPENSSL_NO_PADDING';
  69. }
  70. $config['option'] = constant($config['option']);
  71. if ($config['option'] === null) {
  72. $config['option'] = OPENSSL_NO_PADDING;
  73. }
  74. $config['iv'] = $this->field->{$config['iv']} ?? $config['iv'];
  75. $config['aad'] = $this->field->{$config['aad']} ?? $config['aad'];
  76. if ($config['tag_len']) {
  77. $config['tag'] = substr($config['value'], -$config['tag_len']);
  78. $config['value'] = substr($config['value'], 0, -$config['tag_len']);
  79. }
  80. if (!$config['tag']) {
  81. $config['tag'] = null;
  82. }
  83. }
  84. return $config;
  85. }
  86. protected function cert(&$config, $key)
  87. {
  88. $config['cert_type'] = $config[$key . '_cert_type'];
  89. $config['cert'] = $config[$key . '_cert'];
  90. $config['cert_id'] = $config[$key . '_cert_id'];
  91. if ($config['cert_type'] == 3) {
  92. # 公钥
  93. $config['cert'] = $this->field->{$config['cert']} ?? $config['cert'];
  94. } else {
  95. $cert = false;
  96. #$set = Dever::db('platform_cert', 'api')->find($config['cert_id']);
  97. # 获取账户里的cert
  98. $project = $this->field->account_project;
  99. $account_id = $this->field->account_id;
  100. if ($project && $account_id) {
  101. $cert = Dever::db($project . '/account_cert')->find(['account_id' => $account_id, 'platform_cert_id' => $config['cert_id']], ['order' => 'edate desc']);
  102. }
  103. if (!$cert) {
  104. $config['cert'] = false;
  105. return $config;
  106. }
  107. $this->field->setNumber($cert['number']);
  108. if ($config['cert_type'] == 2) {
  109. $key = 'private';
  110. $method = 'openssl_get_privatekey';
  111. } else {
  112. $key = 'public';
  113. $method = 'openssl_x509_read';
  114. }
  115. if ($cert[$key]) {
  116. $config['cert'] = $cert[$key];
  117. $config['cert'] = $method($config['cert']);
  118. }
  119. }
  120. }
  121. }