public_key = $this->getPublicKey($config['public']); } else { $this->public_key = openssl_pkey_get_public($config['public']); if (!$this->public_key) { die('请检查公钥是否正确'); } } if (is_file($config['private'])) { $this->private_key = $this->getPrivateKey($config['private']); } else { $this->private_key = openssl_pkey_get_private($config['private']); if (!$this->private_key) { die('请检查私钥是否正确'); } } } if ($config['cert_save_path']) $this->cert_save_path = $config['cert_save_path']; } /** * 单例获取对象实例 */ public static function instance($config=array()) { if (!self::$rsa) { if (empty($config)) { $config = [ 'public' => '', 'private' => '', 'cert_save_path' => '' ]; } self::$rsa = new self($config); } return self::$rsa; } /** * 读取文件 */ private function fileGet($file) { if (!file_exists($file)) { die($file . "不是文件"); } return file_get_contents($file); } /** * 获取公钥 */ private function getPublicKey($path) { $pubKey = $this->fileGet($path); if (!$pubKey) { die('请检查公钥路径是否正确'); } return openssl_pkey_get_public($pubKey); } /** * 获取私钥 */ private function getPrivateKey($path) { $priKey = $this->fileGet($path); if (!$priKey) { die('请检查私钥路径是否正确'); } return openssl_pkey_get_private($priKey); } /** * 使用私钥生成签名 * @param string 用于生成签名的字符串 * @return string 签名后的值 */ public function signPrivate($data) { $signature = false; if (openssl_sign($data, $signature, $this->private_key)) { $signature = base64_encode($signature); } return $signature; } /** * 使用公钥验签 * @param $data = array('data'='','signature'='') * @return bool */ public function verifyPublic($data) { $bool = false; if (!$data['data'] || !$data['signature']) { die('数据源或签名值为出错!'); } $result = base64_decode($data['signature']); switch (openssl_verify($data['data'], $result, $this->public_key)) { case 1: $bool = true; break; case 0: case -1: $bool = false; break; default: $bool = false; } return $bool; } /** * 使用公钥加密 */ public function encryptPublic($data) { $crypted = false; if (is_array($data)) { $data = json_encode($data); } $cryp = strrev($data); // 将数据前后反转再加密 if (openssl_public_encrypt($cryp, $crypted, $this->public_key, OPENSSL_PKCS1_PADDING)) { $crypted = base64_encode($crypted); } return $crypted; } /** * 使用公钥分块加密 */ public function chunkEncryptPublic($data, $limit = 117) { if (is_array($data)) { $data = json_encode($data); } $datas = str_split($data, $limit); $crypteds = []; foreach ($datas as $key => $val) { $crypteds[$key] = $this->encryptPublic($val); } return $crypteds; } /** * 使用私钥解密 */ public function decryptPrivate($encrypted) { $decrypted = ''; $data = base64_decode($encrypted); if (openssl_private_decrypt($data, $decrypted, $this->private_key, OPENSSL_PKCS1_PADDING)) { $decrypted = rtrim(strrev($decrypted), '\0'); } return $decrypted; } /** * 使用私钥分块解密 */ public function chunkDecryptPrivate($encrypteds) { $decrypted = ''; $encrypteds = htmlspecialchars_decode($encrypteds); if (!is_array($encrypteds)) { $arr = explode(',', $encrypteds); if ($arr) { $encrypteds = $arr; } else { return json_decode($this->decryptPrivate($encrypteds)); } } foreach ($encrypteds as $key => $val) { $decrypted .= $this->decryptPrivate($val); } $res = json_decode($decrypted, true); if (is_array($res)) return $res; return json_decode($res, true); } /** * 生成公私钥 */ public function createRsa($writeFile=false) { $config = array("config" => $this->openssl_cnf_path); // 生成公私钥 $privkey = openssl_pkey_new($config); openssl_pkey_export($privkey, $private_key, null, $config); // 导出私钥$private_key $public_key = openssl_pkey_get_details($privkey); // 导出公钥$public_key if (!$writeFile) { return array('private_key' => $private_key, 'public_key' => $public_key['key']); } $publicPath = $this->cert_save_path . "rsa_public_key.pem"; // 生成公钥路径 $privatePath = $this->cert_save_path . "rsa_private_key.pem"; // 私钥文件路径 // 生成公钥文件 if (!is_writeable($publicPath)) { chmod($publicPath, 0755); } $fp = fopen($publicPath, "w"); fwrite($fp, $public_key['key']); fclose($fp); // 生成私钥文件 if (!is_writeable($privatePath)) { chmod($privatePath, 0755); } $fp = fopen($privatePath, "w"); fwrite($fp, $private_key); fclose($fp); } /** * 生成证书和密钥 */ public function createCsr($writeFile=false) { $dn = array( "countryName" => 'CN', // 所在国家名称 "stateOrProvinceName" => 'Hunan', // 所在省份名称 "localityName" => 'Changsha', // 所在城市名称 "organizationName" => 'opd', // 注册人姓名 "organizationalUnitName" => 'orico_opd', // 组织名称 "commonName" => 'orico_opd', // 公共名称 "emailAddress" => '735273025@qq.com' // 邮箱 ); $privkeypass = self::SIGN_CERT_PWD; //私钥密码 $config = array( "config" => $this->openssl_cnf_path, "digest_alg" => "sha1", "private_key_bits" => 2048, "private_key_type" => OPENSSL_KEYTYPE_DSA, "encrypt_key" => false ); $privkey = openssl_pkey_new($config); $csr = openssl_csr_new($dn, $privkey, $config); $sscert = openssl_csr_sign($csr, null, $privkey, 365, $config); openssl_x509_export($sscert, $csrkey); // 导出证书$csrkey  openssl_pkcs12_export($sscert, $private_key, $privkey, $privkeypass); // 导出密钥$private_key  if (!$writeFile) { return array('csrkey' => $csrkey, 'private_key_pfx' => $private_key); } $cerpath = $this->cert_save_path . "csrkey.cer"; // 生成证书路径 $pfxpath = $this->cert_save_path . "private_key.pfx"; // 密钥文件路径 // 生成证书文件 if (!is_writeable($cerpath)) { chmod($cerpath, 0755); } $fp = fopen($cerpath, "w"); fwrite($fp, $csrkey); fclose($fp); // 生成密钥文件 if (!is_writeable($pfxpath)) { chmod($pfxpath, 0755); } $fp = fopen($pfxpath, "w"); fwrite($fp, $private_key); fclose($fp); } }