php实现RSA加密类实例
本文实例讲述了php实现RSA加密类。分享给大家供大家参考。具体分析如下:
通过openssl实现的签名、验签、非对称加解密,需要配合x.509证书(如crt和pem)文件使用。
由于各种原因,该类并不十分完善,欢迎各种测试!
<?php
/**
*RSA算法类
*签名及密文编码:base64字符串/十六进制字符串/二进制字符串流
*填充方式:PKCS1Padding(加解密)/NOPadding(解密)
*
*Notice:Onlyacceptsasingleblock.BlocksizeisequaltotheRSAkeysize!
*如密钥长度为1024bit,则加密时数据需小于128字节,加上PKCS1Padding本身的11字节信息,所以明文需小于117字节
*
*@author:linvo
*@version:1.0.0
*@date:2013/1/23
*/
classRSA{
private$pubKey=null;
private$priKey=null;
/**
*自定义错误处理
*/
privatefunction_error($msg){
die('RSAError:'.$msg);//TODO
}
/**
*构造函数
*
*@paramstring公钥文件(验签和加密时传入)
*@paramstring私钥文件(签名和解密时传入)
*/
publicfunction__construct($public_key_file='',$private_key_file=''){
if($public_key_file){
$this->_getPublicKey($public_key_file);
}
if($private_key_file){
$this->_getPrivateKey($private_key_file);
}
}
/**
*生成签名
*
*@paramstring签名材料
*@paramstring签名编码(base64/hex/bin)
*@return签名值
*/
publicfunctionsign($data,$code='base64'){
$ret=false;
if(openssl_sign($data,$ret,$this->priKey)){
$ret=$this->_encode($ret,$code);
}
return$ret;
}
/**
*验证签名
*
*@paramstring签名材料
*@paramstring签名值
*@paramstring签名编码(base64/hex/bin)
*@returnbool
*/
publicfunctionverify($data,$sign,$code='base64'){
$ret=false;
$sign=$this->_decode($sign,$code);
if($sign!==false){
switch(openssl_verify($data,$sign,$this->pubKey)){
case1:$ret=true;break;
case0:
case-1:
default:$ret=false;
}
}
return$ret;
}
/**
*加密
*
*@paramstring明文
*@paramstring密文编码(base64/hex/bin)
*@paramint填充方式(貌似php有bug,所以目前仅支持OPENSSL_PKCS1_PADDING)
*@returnstring密文
*/
publicfunctionencrypt($data,$code='base64',$padding=OPENSSL_PKCS1_PADDING){
$ret=false;
if(!$this->_checkPadding($padding,'en'))$this->_error('paddingerror');
if(openssl_public_encrypt($data,$result,$this->pubKey,$padding)){
$ret=$this->_encode($result,$code);
}
return$ret;
}
/**
*解密
*
*@paramstring密文
*@paramstring密文编码(base64/hex/bin)
*@paramint填充方式(OPENSSL_PKCS1_PADDING/OPENSSL_NO_PADDING)
*@parambool是否翻转明文(WhenpassingMicrosoftCryptoAPI-generatedRSAcyphertext,revertthebytesintheblock)
*@returnstring明文
*/
publicfunctiondecrypt($data,$code='base64',$padding=OPENSSL_PKCS1_PADDING,$rev=false){
$ret=false;
$data=$this->_decode($data,$code);
if(!$this->_checkPadding($padding,'de'))$this->_error('paddingerror');
if($data!==false){
if(openssl_private_decrypt($data,$result,$this->priKey,$padding)){
$ret=$rev?rtrim(strrev($result),"\0"):''.$result;
}
}
return$ret;
}
//私有方法
/**
*检测填充类型
*加密只支持PKCS1_PADDING
*解密支持PKCS1_PADDING和NO_PADDING
*
*@paramint填充模式
*@paramstring加密en/解密de
*@returnbool
*/
privatefunction_checkPadding($padding,$type){
if($type=='en'){
switch($padding){
caseOPENSSL_PKCS1_PADDING:
$ret=true;
break;
default:
$ret=false;
}
}else{
switch($padding){
caseOPENSSL_PKCS1_PADDING:
caseOPENSSL_NO_PADDING:
$ret=true;
break;
default:
$ret=false;
}
}
return$ret;
}
privatefunction_encode($data,$code){
switch(strtolower($code)){
case'base64':
$data=base64_encode(''.$data);
break;
case'hex':
$data=bin2hex($data);
break;
case'bin':
default:
}
return$data;
}
privatefunction_decode($data,$code){
switch(strtolower($code)){
case'base64':
$data=base64_decode($data);
break;
case'hex':
$data=$this->_hex2bin($data);
break;
case'bin':
default:
}
return$data;
}
privatefunction_getPublicKey($file){
$key_content=$this->_readFile($file);
if($key_content){
$this->pubKey=openssl_get_publickey($key_content);
}
}
privatefunction_getPrivateKey($file){
$key_content=$this->_readFile($file);
if($key_content){
$this->priKey=openssl_get_privatekey($key_content);
}
}
privatefunction_readFile($file){
$ret=false;
if(!file_exists($file)){
$this->_error("Thefile{$file}isnotexists");
}else{
$ret=file_get_contents($file);
}
return$ret;
}
privatefunction_hex2bin($hex=false){
$ret=$hex!==false&&preg_match('/^[0-9a-fA-F]+$/i',$hex)?pack("H*",$hex):false;
return$ret;
}
}
测试demo:
<?php
header('Content-Type:text/html;Charset=utf-8;');
include"rsa.php";
echo'<pre>';
$a=isset($_GET['a'])?$_GET['a']:'测试123';
//////////////////////////////////////
$pubfile='E:\ssl\cert\pwd.crt';
$prifile='E:\ssl\cert\pwd.pem';
$m=newRSA($pubfile,$prifile);
$x=$m->sign($a);
$y=$m->verify($a,$x);
var_dump($x,$y);
$x=$m->encrypt($a);
$y=$m->decrypt($x);
var_dump($x,$y);
希望本文所述对大家的php程序设计有所帮助。