Ssl.php 4.9 KB

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