123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- <?php
- namespace loyalsoft;
- /**
- * 使用openssl实现非对称加密,用于安全的通讯中,
- * 可进行签名/验签, 加密/解密
- * @author gwang email:wanggangzero@qq.com
- * @copyright © 2015-12-3, SJZ LoyalSoft Corporation & gwang. All rights reserved.
- */
- class MyRsa
- {
- /**
- * 测试
- */
- public static function Test()
- {
- $path = __DIR__ . DIRECTORY_SEPARATOR . "key";
- $msRsa = new MyRsa($path);
- // $msRsa->createKey();
- $data = "中华人民共和国";
- echo "data: $data";
- $crypted = $msRsa->privEncrypt($data);
- echo "encrypted: $crypted";
- $decrypted = $msRsa->pubDecrypt($crypted);
- echo "decrypted: $decrypted";
- unset($msRsa);
- }
- // 测试签名/验签
- public static function testSign()
- {
- $path = __DIR__ . DIRECTORY_SEPARATOR . "key";
- $msRsa = new MyRsa($path);
- // $msRsa->createKey();
- $data = "中华人民共和国";
- echoLine("data: $data");
- $sign = $msRsa->sign_str($data);
- echoLine("sign: $sign");
- $verify = $msRsa->verify($data, $sign);
- echoLine("verify : $verify");
- unset($msRsa);
- }
- private $_privKey;
- private $_pubKey;
- private $_keyPath; // 密钥保存路径
- /**
- * 构造函数
- * @param string $path 密钥保存路径
- */
- public function __construct($path)
- {
- if (empty($path) || !is_dir($path)) {
- throw new \Exception('Must set the keys save path');
- } $this->_keyPath = $path;
- }
- /**
- * 创建密钥对,保存到 $this->_keyPath
- * @deprecated since version now() 还是用OpenSSL工具生成秘钥吧, 这个函数生成的C#不认, 不知道为什么.-gwang 2018年1月19日14:17:48
- * */
- public function createKey()
- {
- //参数设置
- $config = [
- "digest_alg" => "sha512",
- //文件路径根据自己的要求进行填充
- // "config" => "./conf/openssl.cnf",
- //字节数 512 1024 2048 4096 等
- "private_key_bits" => 1024,
- //加密类型
- "private_key_type" => OPENSSL_KEYTYPE_RSA,
- ];
- $r = openssl_pkey_new($config);
- openssl_pkey_export($r, $privKey);
- $tsday = TimeUtil::dtToday();
- file_put_contents($this->_keyPath . DIRECTORY_SEPARATOR . "key.$tsday.pem", $privKey);
- $this->_privKey = openssl_pkey_get_public($privKey);
- $rp = openssl_pkey_get_details($r);
- $pubKey = $rp['key'];
- file_put_contents($this->_keyPath . DIRECTORY_SEPARATOR . "pub.$tsday.pem", $pubKey);
- $this->_pubKey = openssl_pkey_get_public($pubKey);
- }
- /*
- * setup the private key
- */
- public function setupPrivKey()
- {
- if (is_resource($this->_privKey)) {
- return true;
- }
- $file = $this->_keyPath . DIRECTORY_SEPARATOR . 'key.pem';
- $prk = file_get_contents($file);
- $this->_privKey = openssl_pkey_get_private($prk);
- return true;
- }
- /**
- * setup the public key
- */
- public function setupPubKey()
- {
- if (is_resource($this->_pubKey)) {
- return true;
- }
- $file = $this->_keyPath . DIRECTORY_SEPARATOR . 'pub.pem';
- $puk = file_get_contents($file);
- $this->_pubKey = openssl_pkey_get_public($puk);
- return true;
- }
- /**
- * 生成签名
- * @param array $params
- * @return string sign with base64 encoded
- */
- public function sign_arr($params)
- {
- $content = "";
- if ($params) {
- ksort($params);
- $i = 0;
- foreach ($params as $key => $value) {
- if ($key != "sign") {
- $content .= ($i == 0 ? '' : '&') . $key . '=' . $value;
- $i++;
- }
- }
- }
- return $this->sign_str($content);
- }
- /**
- * 签名
- * @param string $data
- * @return string with base64 encoded
- */
- public function sign_str($data)
- {
- if (!is_string($data)) {
- return null;
- }
- $this->setupPrivKey();
- $sign = null;
- $r = openssl_sign($data, $sign, $this->_privKey);
- if ($r) {
- return base64_encode($sign);
- }
- return null;
- }
- /**
- * 验签
- * @param type $data
- * @param type $sign
- * @return boolean true 通过, false 不通过
- */
- public function verify($data, $sign)
- {
- if (!is_string($data) || !is_string($sign)) {
- return false;
- }
- $this->setupPubKey();
- $r = openssl_verify($data, base64_decode($sign), $this->_pubKey);
- if ($r == 1) {
- return true;
- }
- return false;
- }
- /**
- * 验签(数组)
- * @param array $arr
- * @param string $sign
- * @return boolean true 通过, false 不通过
- */
- public function verify_arr($arr, $sign)
- {
- if (!is_array($arr) || !is_string($sign)) {
- CLog::err("验签防御代码:参数有误", 'RSA');
- return false;
- }
- return $sign == $this->sign_arr($arr);
- }
- /**
- * encrypt with the private key
- */
- public function privEncrypt($data)
- {
- if (!is_string($data)) {
- return null;
- }
- $this->setupPrivKey();
- $encrypted = null;
- $r = openssl_private_encrypt($data, $encrypted, $this->_privKey);
- if ($r) {
- return base64_encode($encrypted);
- }
- return null;
- }
- /**
- * * decrypt with the private key
- */
- public function privDecrypt($encrypted)
- {
- if (!is_string($encrypted)) {
- return null;
- }
- $this->setupPrivKey();
- $encrypted = base64_decode($encrypted);
- $r = openssl_private_decrypt($encrypted, $decrypted, $this->_privKey);
- if ($r) {
- return $decrypted;
- }
- return null;
- }
- /**
- * encrypt with public key
- */
- public function pubEncrypt($data)
- {
- if (!is_string($data)) {
- return null;
- }
- $this->setupPubKey();
- $encrypted = null;
- $r = openssl_public_encrypt($data, $encrypted, $this->_pubKey);
- if ($r) {
- return base64_encode($encrypted);
- }
- return null;
- }
- /**
- * decrypt with the public key
- */
- public function pubDecrypt($crypted)
- {
- if (!is_string($crypted)) {
- return null;
- }
- $this->setupPubKey();
- $crypted = base64_decode($crypted);
- $r = openssl_public_decrypt($crypted, $decrypted, $this->_pubKey);
- if ($r) {
- return $decrypted;
- }
- return null;
- }
- /**
- * 析构函数
- */
- public function __destruct()
- {
- if (is_resource($this->_pubKey)) {
- openssl_free_key($this->_pubKey);
- }
- if (is_resource($this->_privKey)) {
- openssl_free_key($this->_privKey);
- }
- }
- }
|