PHP AES和RSA加密类实现与示例
张成
2016/3
<?php /** * Created by PhpStorm. * User: zc * Date: 2016/3/12 * Time: 13:35 */ /** * Class Base64 * MIME base64 编码数据辅助类 兼顾URL传输 */ class Base64 { public static function base64EncodeForUrl($data) { $str = base64_encode($data); return strtr($str, '+/=', '-_!'); } public static function base64DecodeForUrl($data) { $str = strtr($data, '-_!','+/='); return base64_decode($str); } } /** * Class AES * AES加密类 * */ class AES { //加密私钥 32位 var $private_key = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; //初始化向量 16位 var $iv = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; /** * 加密 * 使用CBC模式 会使用IV 加密强度比ECB模式好 * @param $data * * @return string */ function encryptToken($data) { $padding = 16 - (strlen($data) % 16); //填充补齐长度 为 16的倍数 $data .= str_repeat(chr($padding), $padding); return Base64::base64EncodeForUrl(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $this->private_key, $data, MCRYPT_MODE_CBC, $this->iv)); } /** * 解密 * @param $data * * @return string */ function decryptToken($data) { $data = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $this->private_key, Base64::base64DecodeForUrl($data), MCRYPT_MODE_CBC, $this->iv); $padding = ord($data[strlen($data) - 1]); return substr($data, 0, -$padding); } } /** * Class RSA * * * linux系统生成公私钥对方法: * * openssl genrsa -out rsa_private_key.pem 1024 * openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_key.pem * openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem * 第一条命令生成原始 RSA私钥文件 rsa_private_key.pem, * 第二条命令将原始 RSA私钥转换为 pkcs8格式, * 第三条生成RSA公钥 rsa_public_key.pem * */ abstract class RSA { public $private_key; public $public_key; public $private_resource; public $public_resource; function __construct($private_key = '',$public_key = '') { if(!extension_loaded('openssl')) { throw new Exception('openssl does not loaded!'.PHP_EOL); } $this->private_key = $private_key; $this->public_key = $public_key; $this->init(); } public function init(){} abstract function encode($source); abstract function decode($encrypted); /** * 发签名的使用私钥 * * @param $data 待签名的数据 * * @return string */ public function sign($data){ if($this->private_resource == null){ return ''; } openssl_sign($data,$sign,$this->private_resource); return $sign; } /** * 验证签名的使用对方公开的公钥 * * @param $data 待签名的数据 * @param $signData 签名 * * @return bool */ public function verifySign($data,$signData) { echo $data.PHP_EOL; echo $signData.PHP_EOL; if($this->public_resource == null){ return 0; } return openssl_verify($data,$signData,$this->public_resource); } } /** * Class RSAClient * RSA加密解密 客户端类 */ class RSAClient extends RSA { public function init() { $this->private_resource = openssl_pkey_get_private($this->private_key); if($this->private_resource === false){ throw new Exception('private_resource does not support for RSAServer !'.PHP_EOL); } $this->public_resource = openssl_pkey_get_public($this->public_key); if($this->public_resource === false){ throw new Exception('public_key does not support for RSAClient !'.PHP_EOL); } } function encode($source) { $flag = openssl_public_encrypt($source,$encrypted,$this->public_resource); if($flag){ return Base64::base64EncodeForUrl($encrypted); }else{ return false; } } function decode($encrypted) { $encrypted = Base64::base64DecodeForUrl($encrypted); $flag = openssl_public_encrypt($encrypted,$decrypted,$this->public_resource); if($flag){ return $decrypted; }else{ return false; } } } /** * Class RSAServer * RSA加密解密服务端类 */ class RSAServer extends RSA { public function init() { $this->private_resource = openssl_pkey_get_private($this->private_key); if($this->private_resource === false){ throw new Exception('private_resource does not support for RSAServer !'.PHP_EOL); } $this->public_resource = openssl_pkey_get_public($this->public_key); if($this->public_resource === false){ throw new Exception('public_key does not support for RSAClient !'.PHP_EOL); } } /** * 服务器端加密 用私钥加密 * @param $source * * @return mixed */ function encode($source) { $flag = openssl_private_encrypt($source,$encrypted,$this->private_resource);//私钥加密 if($flag){ return Base64::base64EncodeForUrl($encrypted); }else{ return false; } } /** * 服务器端解密 用私钥解密 * @param $encrypted * * @return mixed */ function decode($encrypted) { $encrypted = Base64::base64DecodeForUrl($encrypted); $flag = openssl_private_decrypt($encrypted,$decrypted,$this->private_resource); if($flag){ return $decrypted; }else{ return false; } } } //客户端私钥和公钥 //私钥 $client_private_key = '-----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQC3//sR2tXw0wrC2DySx8vNGlqt3Y7ldU9+LBLI6e1KS5lfc5jl TGF7KBTSkCHBM3ouEHWqp1ZJ85iJe59aF5gIB2klBd6h4wrbbHA2XE1sq21ykja/ Gqx7/IRia3zQfxGv/qEkyGOx+XALVoOlZqDwh76o2n1vP1D+tD3amHsK7QIDAQAB AoGBAKH14bMitESqD4PYwODWmy7rrrvyFPEnJJTECLjvKB7IkrVxVDkp1XiJnGKH 2h5syHQ5qslPSGYJ1M/XkDnGINwaLVHVD3BoKKgKg1bZn7ao5pXT+herqxaVwWs6 ga63yVSIC8jcODxiuvxJnUMQRLaqoF6aUb/2VWc2T5MDmxLhAkEA3pwGpvXgLiWL 3h7QLYZLrLrbFRuRN4CYl4UYaAKokkAvZly04Glle8ycgOc2DzL4eiL4l/+x/gaq deJU/cHLRQJBANOZY0mEoVkwhU4bScSdnfM6usQowYBEwHYYh/OTv1a3SqcCE1f+ qbAclCqeNiHajCcDmgYJ53LfIgyv0wCS54kCQAXaPkaHclRkQlAdqUV5IWYyJ25f oiq+Y8SgCCs73qixrU1YpJy9yKA/meG9smsl4Oh9IOIGI+zUygh9YdSmEq0CQQC2 4G3IP2G3lNDRdZIm5NZ7PfnmyRabxk/UgVUWdk47IwTZHFkdhxKfC8QepUhBsAHL QjifGXY4eJKUBm3FpDGJAkAFwUxYssiJjvrHwnHFbg0rFkvvY63OSmnRxiL4X6EY yI9lblCsyfpl25l7l5zmJrAHn45zAiOoBrWqpM5edu7c -----END RSA PRIVATE KEY-----'; //公钥 $client_public_key = '-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC3//sR2tXw0wrC2DySx8vNGlqt 3Y7ldU9+LBLI6e1KS5lfc5jlTGF7KBTSkCHBM3ouEHWqp1ZJ85iJe59aF5gIB2kl Bd6h4wrbbHA2XE1sq21ykja/Gqx7/IRia3zQfxGv/qEkyGOx+XALVoOlZqDwh76o 2n1vP1D+tD3amHsK7QIDAQAB -----END PUBLIC KEY-----'; //服务端私钥和公钥 $server_pubkey ='-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC3//sR2tXw0wrC2DySx8vNGlqt 3Y7ldU9+LBLI6e1KS5lfc5jlTGF7KBTSkCHBM3ouEHWqp1ZJ85iJe59aF5gIB2kl Bd6h4wrbbHA2XE1sq21ykja/Gqx7/IRia3zQfxGv/qEkyGOx+XALVoOlZqDwh76o 2n1vP1D+tD3amHsK7QIDAQAB -----END PUBLIC KEY-----';; $server_prikey ='-----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQC3//sR2tXw0wrC2DySx8vNGlqt3Y7ldU9+LBLI6e1KS5lfc5jl TGF7KBTSkCHBM3ouEHWqp1ZJ85iJe59aF5gIB2klBd6h4wrbbHA2XE1sq21ykja/ Gqx7/IRia3zQfxGv/qEkyGOx+XALVoOlZqDwh76o2n1vP1D+tD3amHsK7QIDAQAB AoGBAKH14bMitESqD4PYwODWmy7rrrvyFPEnJJTECLjvKB7IkrVxVDkp1XiJnGKH 2h5syHQ5qslPSGYJ1M/XkDnGINwaLVHVD3BoKKgKg1bZn7ao5pXT+herqxaVwWs6 ga63yVSIC8jcODxiuvxJnUMQRLaqoF6aUb/2VWc2T5MDmxLhAkEA3pwGpvXgLiWL 3h7QLYZLrLrbFRuRN4CYl4UYaAKokkAvZly04Glle8ycgOc2DzL4eiL4l/+x/gaq deJU/cHLRQJBANOZY0mEoVkwhU4bScSdnfM6usQowYBEwHYYh/OTv1a3SqcCE1f+ qbAclCqeNiHajCcDmgYJ53LfIgyv0wCS54kCQAXaPkaHclRkQlAdqUV5IWYyJ25f oiq+Y8SgCCs73qixrU1YpJy9yKA/meG9smsl4Oh9IOIGI+zUygh9YdSmEq0CQQC2 4G3IP2G3lNDRdZIm5NZ7PfnmyRabxk/UgVUWdk47IwTZHFkdhxKfC8QepUhBsAHL QjifGXY4eJKUBm3FpDGJAkAFwUxYssiJjvrHwnHFbg0rFkvvY63OSmnRxiL4X6EY yI9lblCsyfpl25l7l5zmJrAHn45zAiOoBrWqpM5edu7c -----END RSA PRIVATE KEY-----'; $a = new AES(); $cli = new RSAClient($client_private_key,$server_pubkey); $ser = new RSAServer($server_prikey,$client_public_key); $param['key'] = $cli->encode($a->private_key); $param['sign'] = Base64::base64EncodeForUrl($cli->sign($param['key']));//签名 $param['data'] = $a->encryptToken('zhangcheng'); var_dump($param); $dkey = $ser->decode($param['key']); echo $ser->decode($param['key']);//使用RSA服务端解密 AES的私钥 校验AES私钥 echo PHP_EOL; echo $a->decryptToken($param['data']);//使用AES解密正文数据 echo PHP_EOL; //校验 var_dump( $ser->verifySign($param['key'] , Base64::base64DecodeForUrl($param['sign'])) );