php實(shí)現(xiàn)RSA加密類實(shí)例
本文實(shí)例講述了php實(shí)現(xiàn)RSA加密類。分享給大家供大家參考。具體分析如下:
通過(guò)openssl實(shí)現(xiàn)的簽名、驗(yàn)簽、非對(duì)稱加解密,需要配合x.509證書(如crt和pem)文件使用。
由于各種原因,該類并不十分完善,歡迎各種測(cè)試!
<?php
/**
* RSA算法類
* 簽名及密文編碼:base64字符串/十六進(jìn)制字符串/二進(jìn)制字符串流
* 填充方式: PKCS1Padding(加解密)/NOPadding(解密)
*
* Notice:Only accepts a single block. Block size is equal to the RSA key size!
* 如密鑰長(zhǎng)度為1024 bit,則加密時(shí)數(shù)據(jù)需小于128字節(jié),加上PKCS1Padding本身的11字節(jié)信息,所以明文需小于117字節(jié)
*
* @author: linvo
* @version: 1.0.0
* @date: 2013/1/23
*/
class RSA{
private $pubKey = null;
private $priKey = null;
/**
* 自定義錯(cuò)誤處理
*/
private function _error($msg){
die('RSA Error:' . $msg); //TODO
}
/**
* 構(gòu)造函數(shù)
*
* @param string 公鑰文件(驗(yàn)簽和加密時(shí)傳入)
* @param string 私鑰文件(簽名和解密時(shí)傳入)
*/
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;
}
/**
* 驗(yàn)證簽名
*
* @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 是否翻轉(zhuǎn)明文(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;
}
// 私有方法
/**
* 檢測(cè)填充類型
* 加密只支持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;
}
}
測(cè)試demo:
<?php
header('Content-Type:text/html;Charset=utf-8;');
include "rsa.php";
echo '<pre>';
$a = isset($_GET['a']) ? $_GET['a'] : '測(cè)試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);
希望本文所述對(duì)大家的php程序設(shè)計(jì)有所幫助。
- 淺談PHP SHA1withRSA加密生成簽名及驗(yàn)簽
- PHP7.1實(shí)現(xiàn)的AES與RSA加密操作示例
- ThinkPHP實(shí)現(xiàn)的rsa非對(duì)稱加密類示例
- PHP封裝的非對(duì)稱加密RSA算法示例
- 基于PHP RSA密文過(guò)長(zhǎng)加密解密 越過(guò)1024的解決方法
- PHP實(shí)現(xiàn)RSA加解密算法示例(生成密鑰位數(shù)為1024位的方法)
- PHP的RSA加密解密方法以及開發(fā)接口使用
- PHP檢測(cè)接口Traversable用法詳解
- PHP實(shí)現(xiàn)的MD5結(jié)合RSA簽名算法實(shí)例
- PHP實(shí)現(xiàn)RSA簽名生成訂單功能【支付寶示例】
- php rsa 加密,解密,簽名,驗(yàn)簽詳解
- php基于openssl的rsa加密解密示例
- PHP rsa加密解密使用方法
- 詳解PHP使用非對(duì)稱加密算法RSA
相關(guān)文章
php項(xiàng)目中類的自動(dòng)加載實(shí)例講解
在本篇文章里小編給大家整理的是關(guān)于php項(xiàng)目中類的自動(dòng)加載的實(shí)例內(nèi)容以及相關(guān)代碼,需要的朋友們學(xué)習(xí)下。2019-09-09
解析PHP 使用curl提交json格式數(shù)據(jù)
本篇文章是對(duì)PHP中使用curl提交json格式數(shù)據(jù)的實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
PHP 動(dòng)態(tài)隨機(jī)生成驗(yàn)證碼類代碼
這個(gè)利用PHP動(dòng)態(tài)隨機(jī)生成驗(yàn)證碼的類是在LAMP的書上看到的。感覺寫的很好就收藏了下來(lái)。2010-04-04
PHP數(shù)組常用函數(shù)實(shí)例小結(jié)
這篇文章主要介紹了PHP數(shù)組常用函數(shù),結(jié)合實(shí)例形式總結(jié)分析了php針對(duì)數(shù)組的統(tǒng)計(jì)、計(jì)算、去重、過(guò)濾等相關(guān)函數(shù)使用技巧,需要的朋友可以參考下2018-08-08
php將print_r處理后的數(shù)據(jù)還原為原始數(shù)組的解決方法
下面小編就為大家?guī)?lái)一篇php中將print_r處理后的數(shù)據(jù)還原為原始數(shù)組的方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考2016-11-11
php將文件夾打包成zip文件的簡(jiǎn)單實(shí)現(xiàn)方法
下面小編就為大家?guī)?lái)一篇php將文件夾打包成zip文件的簡(jiǎn)單實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-10-10
PHP響應(yīng)post請(qǐng)求上傳文件的方法
這篇文章主要介紹了PHP響應(yīng)post請(qǐng)求上傳文件的方法,涉及php針對(duì)post傳輸數(shù)據(jù)處理的相關(guān)技巧,需要的朋友可以參考下2015-12-12
基于PHP實(shí)現(xiàn)微博熱搜實(shí)時(shí)監(jiān)控平臺(tái)
在學(xué)習(xí)、“脫發(fā)”之余,便是去微博看看有沒有發(fā)生什么有趣的事情,或是了解一下正在發(fā)生著哪些“大事”,亦或是某些讓我久久不能平復(fù)的事…本文將用PHP實(shí)現(xiàn)微博熱搜實(shí)時(shí)監(jiān)控平臺(tái),需要的可以參考一下2022-06-06
php設(shè)計(jì)模式之適配器模式原理、用法及注意事項(xiàng)詳解
這篇文章主要介紹了php設(shè)計(jì)模式之適配器模式原理、用法及注意事項(xiàng),結(jié)合實(shí)例形式分析了php適配器模式的定義、用法及出現(xiàn)的問(wèn)題與解決方法,需要的朋友可以參考下2019-09-09

