RSA签名和验证封装

运行环境:

apache+PHP

当然,打开PHP的openSSL扩展是必须的,方法请问度娘

灵活性考虑,封装为两个类,一个私钥,用于签名,一个公钥,用于验签,2个类都支持从文件加载密钥

私钥类:

<?php
/**
 * @todo RSA私钥
 * @author jixiaolong
 *
 */
class RSAPrivateKey {
    private $privateKeyId;
	
	function __construct($keyFile) {
	    $this->privateKeyId = null;
	    try {
    	    $this->loadKeyFile($keyFile);
	    }
	    catch (Exception $e){
	        throw $e;
	    }
	}
	
	function __destruct() {
	
	}
	
	/**
	 * @todo 通过私钥文件加载私钥
	 * @param string $keyFile 文件名
	 */
	private function loadKeyFile($keyFile){
	    if (!file_exists($keyFile)){
	        $message = '私钥文件'.$keyFile.'不存在';
	        throw new Exception($message, 0);
	    }
	    $privateKey = file_get_contents($keyFile);
	    if (false === $privateKey){
	        $message = '从私钥文件'.$keyFile.'读取私钥信息失败';
	        throw new Exception($message, 0);
	    }
	    $privateKeyId = openssl_get_privatekey($privateKey);
	    if (false === $privateKeyId){
	        $message = '活动私钥打开失败';
	        throw new Exception($message, 0);
	    }
	    $this->privateKeyId = $privateKeyId;
	}
	
	/**
	 * @todo 签名
	 * @param string $sourceStr 待签名的字符串
	 */
	public function sign($sourceStr){
	    if (null == $this->privateKeyId){
	        $message = '没有可用的私钥,请检查是否正确初始化私钥对象';
	        throw new Exception($message, 0);
	    }
	    $signature = '';
	    $ok = openssl_sign($sourceStr, $signature, $this->privateKeyId);
	    if (!$ok){
	        $message = 'openssl_sign调用出错';
	        throw new Exception($message, 0);
	    }
	    return $signature;
	}
}

公钥类


<?php
/**
 * @todo RSA公钥
 * @author jixiaolong
 *
 */
class RSAPublicKey {
    private $publicKeyId;
	
	function __construct($keyFile) {
	    $this->publicKeyId = null;
	    try {
    	    $this->loadKeyFile($keyFile);
	    }
	    catch (Exception $e){
	        throw $e;
	    }
	}
	
	function __destruct() {
	
	}
	
	/**
	 * @todo 通过私钥文件加载私钥
	 * @param string $keyFile 文件名
	 */
	private function loadKeyFile($keyFile){
	    if (!file_exists($keyFile)){
	        $message = '公钥文件'.$keyFile.'不存在';
	        throw new Exception($message, 0);
	    }
	    $publicKey = file_get_contents($keyFile);
	    if (false === $publicKey){
	        $message = '从公钥文件'.$keyFile.'读取公钥信息失败';
	        throw new Exception($message, 0);
	    }
	    $publicKeyId = openssl_get_publickey($publicKey);
	    if (false === $publicKeyId){
	        $message = '活动公钥打开失败';
	        throw new Exception($message, 0);
	    }
	    $this->publicKeyId = $publicKeyId;
	}
	
	/**
	 * @todo 验证
	 * @param string $sourceStr 签名前字符串
	 * @param string $signedStr 签名后字符串
	 * @throws Exception
	 * @return boolean 通过/不通过
	 */
	public function verify($sourceStr,$signedStr){
	    if (null == $this->publicKeyId){
	        $message = '没有可用的公钥,请检查是否正确初始化公钥对象';
	        throw new Exception($message, 0);
	    }
	   	$ok = openssl_verify ( $sourceStr, $signedStr, $this->publicKeyId );
	    if (-1 == $ok){
	        $message = 'openssl_verify调用出错';
	        throw new Exception($message, 0);
	    }
	    $result = 1==$ok ? true : false;
	   	return $result;
	}
}

simple test 测试文件:

<?php
require_once '../../fmis_test.inc.php';
require_once(SIMPLE_TEST_PATH.'autorun.php');
require_once(SIMPLE_TEST_PATH.'unit_tester.php');

/** 
 * @author jixiaolong
 * 
 * 
 */
class TestTonglianRSA extends UnitTestCase {
	
	/**
	 * 
	 * @param  string $label     Name of test case. Will use
the class name if none specified.
 
	 * @access  public
      
	 */
    public  function __construct() {
        parent::__construct(false);
    }
	
	/**
	 * 
	 */
	function __destruct() {
	
	}
	
	public function testPublicKey(){
	    $data = '0123456789abc';
	    $result = 'Jq4TkKIIFa4VGGCyavsrtnma4p1dIvxxH19ITjAdCuax9PoS8OukGA2MX+ictrwboPayMk3pcBgS8domVRu8oOr4sVR2YanASE9VoQMPkcukzx7NdJBKi47CBsWs+aBnCCrmB78+h3vpQ7Lf/tJLog848yf1xxkwp82zAuNzhtI=';
	    $result = base64_decode($result);
	    $publicKeyFile = WEB_PATH.'interface/tonglian/cli_public.pem';
	    $publicKey = file_get_contents($publicKeyFile);
	    $publicKeyId = openssl_get_publickey($publicKey);
	    $ok = openssl_verify ( $data, $result, $publicKeyId );
	    $this->assertEqual(1, $ok, '签名验证通过');
	}
	
	public function testPrivateKey(){
	    $data = '0123456789abc';
	    $result = 'Jq4TkKIIFa4VGGCyavsrtnma4p1dIvxxH19ITjAdCuax9PoS8OukGA2MX+ictrwboPayMk3pcBgS8domVRu8oOr4sVR2YanASE9VoQMPkcukzx7NdJBKi47CBsWs+aBnCCrmB78+h3vpQ7Lf/tJLog848yf1xxkwp82zAuNzhtI=';
	    $result = base64_decode($result);
	    $privateKeyFile = WEB_PATH.'interface/tonglian/cli_private.pem';
	    $privateKey = file_get_contents($privateKeyFile);
	    $privateKeyId = openssl_get_privatekey($privateKey);
	    $signature = '';
	    $ok = openssl_sign($data, $signature, $privateKeyId);
	    $this->assertEqual($result, $signature, '签名后相等');
	    $this->assertTrue($ok, '签名没有报错' );
	}
}

?>



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值