PHP RSA签名及验签

作者: jaclon 分类: Linux, PHP 发布时间: 2015-10-26 13:51 ė 6没有评论

最近在做一个接口,因为涉及的权限比较大,做了ip访问限制还要证书认证。下面就记录一下使用证书签名、验签的过程。

一,使用openssl生成私钥和公钥。首先生成一个1024位的私钥

openssl genrsa -out private.pem 1024

然后根据私钥导出公钥

openssl rsa -in private.pem -pubout -out public.pem

这样我们就有了一个私钥和一个公钥,将私钥保留在自己服务器上,公钥分配给客户端。

二,客户端签名

客户端想要访问服务接口,必须生成一个签名数据,服务端回将根据这个签名判断用户真实性。签名字符串由查询条件组成,先根据字段名排序,然后拼接成一个查询字符串(像a=1&b=2)。将查询字符串生成哈希值,可以是md5或sha1;然后使用公钥对哈希值进行加密,并对密文进行base64编码

三,服务端验签

同样将请求参数排序组成查询字符串并生成哈希值;将签名密文base64解码然后用私钥解密;将解密出的字符串与前面生成的哈希值进行比较,如果一致就验签成功,否则失败。

四,参考代码

/**
 * RSA 密钥加密,解密
 *
 * @author Administrator
 *
 */
class Rsa
{

    /**
     * resource identifier
     *
     * @var resource
     */
    private $private_key = null;

    /**
     * resource identifier
     *
     * @var resource
     */
    private $public_key = null;

    /**
     * Logger
     *
     * @var Logger
     */
    private $logger = null;

    public function __construct()
    {
        $this->logger = Factory::create('Logger');
        
        $filename = APP_ROOT . '/rsa/rsa_private_key.pem';
        if (! file_exists($filename)) {
            throw new Exception("Rsa private file {$filename} not exist.");
        }
        if (($this->private_key = openssl_pkey_get_private(file_get_contents($filename))) === false) {
            throw new Exception("get rsa private key failure.");
        }
    }
    
    /**
     * 生成签名
     *
     * @param array $data
     * @return string
     */
    function sign($data)
    {
        ksort($data);
        
        $sign = array();
        foreach ($data as $key => $value) {
            $sign[] = "{$key}={$value}";
        }
        
        $hash = sha1(implode('&', $sign));
        
        openssl_public_encrypt($hash, $crypted, $this->public_key);
    
        return base64_encode($crypted);
    }
    
    /**
     * 验签
     *
     * @param array $data
     * @param string $sign
     * @return boolean
     */
    public function verfiy($data, $sign)
    {
        ksort($data);
        $_tmp = array();
        foreach ($data as $key => $value) {
            $_tmp[] = "{$key}={$value}";
        }
        $signStr = sha1(implode('&', $_tmp));
        $bool = openssl_private_decrypt(base64_decode($sign), $decrypted, $this->private_key);
        if($bool && $decrypted == $signStr) {
            return true;
        }
        
        return false;
    }
    
    public function __destruct()
    {
        openssl_free_key($this->private_key);
    }
}

本文出自 肥蕉博客@IT技术,热门话题,生活随笔,美图欣赏,转载时请注明出处及相应链接。

本文永久链接: http://www.bananawolf.com/html/2015/10/992.html

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*

Ɣ回顶部