php实现RSA加密类实例
来源: 阅读:7130 次 日期:2015-03-30 11:41:00
温馨提示: 小编为您整理了“php实现RSA加密类实例”,方便广大网友查阅!

这篇文章主要介绍了php实现RSA加密类,实例分析了php自定义RSA类实现加密与解密的技巧,非常具有实用价值,需要的朋友可以参考下

本文实例讲述了php实现RSA加密类。分享给大家供大家参考。具体分析如下:

通过openssl实现的签名、验签、非对称加解密,需要配合x.509证书(如crt和pem)文件使用。

由于各种原因,该类并不十分完善,欢迎各种测试!

<?php

/**

* RSA算法类

* 签名及密文编码:base64字符串/十六进制字符串/二进制字符串流

* 填充方式: PKCS1Padding(加解密)/NOPadding(解密)

*

* Notice:Only accepts a single block. Block size is equal to the RSA key size!

* 如密钥长度为1024 bit,则加密时数据需小于128字节,加上PKCS1Padding本身的11字节信息,所以明文需小于117字节

*

* @author: linvo

* @version: 1.0.0

* @date: 2013/1/23

*/

class RSA{

private $pubKey = null;

private $priKey = null;

/**

* 自定义错误处理

*/

private function _error($msg){

die('RSA Error:' . $msg); //TODO

}

/**

* 构造函数

*

* @param string 公钥文件(验签和加密时传入)

* @param string 私钥文件(签名和解密时传入)

*/

public function __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);

}

}

/**

* 生成签名

*

* @param string 签名材料

* @param string 签名编码(base64/hex/bin)

* @return 签名值

*/

public function sign($data, $code = 'base64'){

$ret = false;

if (openssl_sign($data, $ret, $this->priKey)){

$ret = $this->_encode($ret, $code);

}

return $ret;

}

/**

* 验证签名

*

* @param string 签名材料

* @param string 签名值

* @param string 签名编码(base64/hex/bin)

* @return bool

*/

public function verify($data, $sign, $code = 'base64'){

$ret = false;

$sign = $this->_decode($sign, $code);

if ($sign !== false) {

switch (openssl_verify($data, $sign, $this->pubKey)){

case 1: $ret = true; break;

case 0:

case -1:

default: $ret = false;

}

}

return $ret;

}

/**

* 加密

*

* @param string 明文

* @param string 密文编码(base64/hex/bin)

* @param int 填充方式(貌似php有bug,所以目前仅支持OPENSSL_PKCS1_PADDING)

* @return string 密文

*/

public function encrypt($data, $code = 'base64', $padding = OPENSSL_PKCS1_PADDING){

$ret = false;

if (!$this->_checkPadding($padding, 'en')) $this->_error('padding error');

if (openssl_public_encrypt($data, $result, $this->pubKey, $padding)){

$ret = $this->_encode($result, $code);

}

return $ret;

}

/**

* 解密

*

* @param string 密文

* @param string 密文编码(base64/hex/bin)

* @param int 填充方式(OPENSSL_PKCS1_PADDING / OPENSSL_NO_PADDING)

* @param bool 是否翻转明文(When passing Microsoft CryptoAPI-generated RSA cyphertext, revert the bytes in the block)

* @return string 明文

*/

public function decrypt($data, $code = 'base64', $padding = OPENSSL_PKCS1_PADDING, $rev = false){

$ret = false;

$data = $this->_decode($data, $code);

if (!$this->_checkPadding($padding, 'de')) $this->_error('padding error');

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

*

* @param int 填充模式

* @param string 加密en/解密de

* @return bool

*/

private function _checkPadding($padding, $type){

if ($type == 'en'){

switch ($padding){

case OPENSSL_PKCS1_PADDING:

$ret = true;

break;

default:

$ret = false;

}

} else {

switch ($padding){

case OPENSSL_PKCS1_PADDING:

case OPENSSL_NO_PADDING:

$ret = true;

break;

default:

$ret = false;

}

}

return $ret;

}

private function _encode($data, $code){

switch (strtolower($code)){

case 'base64':

$data = base64_encode(''.$data);

break;

case 'hex':

$data = bin2hex($data);

break;

case 'bin':

default:

}

return $data;

}

private function _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;

}

private function _getPublicKey($file){

$key_content = $this->_readFile($file);

if ($key_content){

$this->pubKey = openssl_get_publickey($key_content);

}

}

private function _getPrivateKey($file){

$key_content = $this->_readFile($file);

if ($key_content){

$this->priKey = openssl_get_privatekey($key_content);

}

}

private function _readFile($file){

$ret = false;

if (!file_exists($file)){

$this->_error("The file {$file} is not exists");

} else {

$ret = file_get_contents($file);

}

return $ret;

}

private function _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 = new RSA($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程序设计有所帮助。

更多信息请查看IT技术专栏

更多信息请查看网络编程
手机网站地址:php实现RSA加密类实例
由于各方面情况的不断调整与变化, 提供的所有考试信息和咨询回复仅供参考,敬请考生以权威部门公布的正式信息和咨询为准!

2025国考·省考课程试听报名

  • 报班类型
  • 姓名
  • 手机号
  • 验证码
关于我们 | 联系我们 | 人才招聘 | 网站声明 | 网站帮助 | 非正式的简要咨询 | 简要咨询须知 | 加入群交流 | 手机站点 | 投诉建议
工业和信息化部备案号:滇ICP备2023014141号-1 云南省教育厅备案号:云教ICP备0901021 滇公网安备53010202001879号 人力资源服务许可证:(云)人服证字(2023)第0102001523号
云南网警备案专用图标
联系电话:0871-65317125(9:00—18:00) 获取招聘考试信息及咨询关注公众号:
咨询QQ:526150442(9:00—18:00)版权所有:
云南网警报警专用图标
Baidu
map