RSA签名和验证封装

来源:互联网 发布:mac os 登录界面 其他 编辑:程序博客网 时间:2024/05/16 17:14

运行环境:

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 测试文件:

<?phprequire_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 usethe 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, '签名没有报错' );}}?>



原创粉丝点击