这篇文章主要介绍使用PHP开发接口,数据实现RSA加密解密后使用,实例分析了PHP自定义RSA类实现加密与解密的技巧,非常具有实用价值,需要的朋友可以参考下。

简单介绍RSA:

RSA加密算法是最常用的非对称加密算法,CFCA在证书服务中离不了它。但是有不少新手对它不太了解。下面仅作简要介绍。RSA是第一个比较完善的公开密钥算法,它既能用于加密,也能用于数字签名。RSA以它的三个发明者Ron Rivest, Adi Shamir, Leonard Adleman的名字首字母命名,这个算法经受住了多年深入的密码分析,虽然密码分析者既不能证明也不能否定RSA的安全性,但这恰恰说明该算法有一定的可信性,目前它已经成为最流行的公开密钥算法。RSA的安全基于大数分解的难度。其公钥和私钥是一对大素数(100到200位十进制数或更大)的函数。从一个公钥和密文恢复出明文的难度,等价于分解两个大素数之积(这是公认的数学难题)。

下面为具体类:Rsa.class.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字节

*/

class RSA

{

private $pubKey = null;

private $priKey = null;

/**

* 构造函数

*/

public function __construct()

{

// 需要开启openssl扩展

if (!extension_loaded("openssl")) {

$this->_error("Please open the openssl extension first.");

}

}

/**

* 读取公钥和私钥

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

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

*/

public function init($public_key_file = '', $private_key_file = '')

{

if ($public_key_file) {

$this->_getPublicKey($public_key_file);

}

if ($private_key_file) {

$this->_getPrivateKey($private_key_file);

}

}

/**

* 自定义错误处理

*/

private function _error($msg)

{

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

}

/**

* 检测填充类型

* 加密只支持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;

}

/**

* 生成Rsa公钥和私钥

* @param int $private_key_bits 建议:[512, 1024, 2048, 4096]

* @return array

*/

public function generate(int $private_key_bits = 1024)

{

$rsa = [

"private_key" => "",

"public_key" => ""

];

$config = [

"digest_alg" => "sha512",

"private_key_bits" => $private_key_bits, #此处必须为int类型

"private_key_type" => OPENSSL_KEYTYPE_RSA,

];

//创建公钥和私钥

$res = openssl_pkey_new($config);

//提取私钥

openssl_pkey_export($res, $rsa['private_key']);

//生成公钥

$rsa['public_key'] = openssl_pkey_get_details($res)["key"];

/*Array

(

[bits] => 512

[key] =>

[rsa] =>

[type] => 0

)*/

return $rsa;

}

/**

* 生成签名

*

* @param string 签名材料

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

* @return bool|string 签名值

*/

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;

}

}

RSA类的使用:use.php

if (!class_exists("RSA")) {

require_once "Rsa.class.php";

}

$private_key_file = __DIR__ . "/cert/private_key.pem";

$public_key_file = __DIR__ . "/cert/public_key.pem";

$rsa = new RSA();

// 没有就生成一对

if (!file_exists($private_key_file) || !file_exists($public_key_file)) {

$key = $rsa->generate();

file_put_contents($private_key_file, $key['private_key'], LOCK_EX);

file_put_contents($public_key_file, $key['public_key'], LOCK_EX);

} else {

$key = [

"private_key" => file_get_contents($private_key_file),

"public_key" => file_get_contents($public_key_file)

];

}

//显示数据

echo "private_key:\n" . $key['private_key'] . "\n\r";

echo "public_key:\n" . $key['public_key'] . "\n\r";

//要加密的数据

$data = "Web site:http://blog.kilvn.com";

echo '加密的数据:' . $data, "\n-------------------------------\n";

$rsa->init($public_key_file, $private_key_file);

//加密

$encrypt = $rsa->encrypt($data);

echo "公钥加密后的数据: " . $encrypt . "\n";

//解密

$decrypt = $rsa->decrypt($encrypt);

echo "私钥解密后的数据: " . $decrypt, "\n-------------------------------\n";

//签名

$sign = $rsa->sign($data);

echo "签名的数据: " . $sign . "\n";

//验证

$verify = $rsa->verify($data, $sign);

echo "验证的数据: " . $verify . "\n", "\n-------------------------------\n";

运行结果如下:

/usr/bin/php /Volumes/Mac软件/WEB/www/use.php

private_key:

-----BEGIN PRIVATE KEY-----

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

mpPQ1kaLJ7QoBD/vT74UhxpqUgCma/Q=

-----END PRIVATE KEY-----

public_key:

-----BEGIN PUBLIC KEY-----

MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwGji+aUGELbI6sa7ifb0

W9QYCp9aMSy0zg5TXV/fDmg/9/hAqjRpTeLThLSxeTNPmzf2VZ9jvrZ7IjkYldfA

2VOe4x91DosU1Fniwf6TYuNemM3H/DK9dGuFXzI1jsiiAobyd5Jb5Ptt0HWLgKNb

jXquh8UddadHgaeKwlbtYYIypb9hhf4ocywQc2dbBBS6e7RpI/XQr+TDkhZPvUYa

4lAaDnPdbc9V75qE/WU9Q2ACiw6jtrcpL1nH5Hif4OHrAHrKLOUyUhUXdkKDFjxN

aZfXxDEUqxLkUw7PXlmww3Rcr3S5MQVP9UXqgHlvOQOYiddXYY81XKA5pXKcWIrA

xjbeUPmVW7UmCFOlYcV/j+rVNDMokQqUragMi+pqpYkzXum7UXB5zjsB8kMVx8l4

/0M5vNk4XGzFCbj4pdsLwxRFW7AVqHqRiGYEEEkl/UpHIl+T+aEZXQI/uAa0q9+R

BoqXVqMqmoYT6R5wPUOliDYchAQUxJkGVow60Y7kVrtIlqPvOG4ugLLpKRTiT+Tz

4mtmMEX+N+UmrAKABJUiGj7JD/lLPWAIKvOx+WlB47k2bTVZp5yTweezU0nOnaU5

gdoWqemWo5EC7JXO73ItLcKGQIY3qUu9tUTXUKTDO/XiDvPP04ggE9bODLfvoSBS

Ph5ANrtx0wxRMeu+VNoeqx8CAwEAAQ==

-----END PUBLIC KEY-----

加密的数据:Web site:http://blog.kilvn.com

-------------------------------

公钥加密后的数据: WJ3JtHA9h+fJyPgl4WNtmplqexi6AvBCP0yC4zFo8AsgHyIu2u5Jt/olDw8Hmjmy4++XjdJwlKC9pNwNTiuj/TvDoWAulDJSgmrTZ/Jrp78K8Puik8n3Zudtmqj9rMMKAwgaX4t8+QRA+tBs5HiRUBpDsKPL8rejqIYZwMwxf67ldbwWFUtuFb8OWvG6EeQjPoKV2mOWi7/KnNFTLc6970sWTgcVe53KeqWrNyHvHLhQda3uom8lf1eOwOrOmhtI1sQdihH36LATCzObcDDsRTJr2oW3Y2d1Sx1npVJ92AvOmOVxFcena8ppkZ+cCRWAxTbiZejdLv9dGCn227yEm5/A5b1MXSHxZcXQ56Vy56Lo735+G6V5zkupVbQJrZBAJg0iDJPi6DFzffLMlTmRlszmiGxg67lxbKQQMhpYkVgZ9PfgYmXzUPVZSXRCz7zGkrP7qqAmbA2tGxRadh1FgekDmb8lSYEbLP6w1gKv5eJTCWYAeUTYuSHsLvCzF2+rJfRz9XrYYVaYAz5ECPCSCOSldENu97Ol612FWJuLZZNFiTLfpkqTYIvgSVGnqbuIMxU+HIifC+/cHabwSpvJ7q2lGmtdcv5mmHfi2V2XpB7SRfe67sbBIeIhF0XOqFoOf1VuhsC+ZP0INV1DIQVvTmivl5+IrORhrxc1c090Eso=

私钥解密后的数据: Web site:http://blog.kilvn.com

-------------------------------

签名的数据: enU5lIt8t7R5nsWw0OK7O8n4yttwo4cR44MDCqr8l4CmobLKgsFJyNskY33EtusisWST8UQconXtRxscEWrFXZTO74xsLKVLP1ZffJZyeRB0hiygNk/h3rZgtZXzGvMDBuOHBn40f4x+DQ83eZuvNPNNjA6nbuoBvyKT7WiP3bQ9HeJQBj7hfQhHbGYnOLwXTvXUbJDhDfpX6Ux4pAz9rjV14s9eKyfmncH0gIbHQDpMd+B06cdKi8i3pX2tGzPleEw9XRIfu1fkDxZ4J9ZruTUDUU0V5jhi+YlBFDo7Hsj3wsAVPTwOIgoRVwggaFCNeXLqx2u0u4BHj0FxJ6Qk2CC8izhcSoVQCfhrS3g9rUP5jCX4JP62kPJ1tIrxx2T+xs2tbdppe7q4Wx6EuIlZvWpnc7oHmPRP2Z3wEfsn49n8wI2f0zSYq3YmyrO0yEFT5bpvLggf6eyIsnnOO/uI/QfksAzSoKuJ3Wf6v0jYZrij/Y6d0jXIkn1MQpFjk5ZA4Dajt2frAzPXViqgdO8YuMFCFD5U2V6GnSYQ8xLR1V88zm3bH/baqqQFOMV0wMaZh9UtgBT5mCRXnUtYHdSjAhfj9xygOtw61p66EKO4Ykf7yxpivOI1QNn1hzA52MPktOTJwitUQXvSUDB5mgkjCPbS05LitAGU71REQ1urk5w=

验证的数据: 1

-------------------------------

Process finished with exit code 0

相关参考:

daoi php_使用php生成RSA公钥私钥及进行加密解密和签名验证相关推荐

  1. 使用keytool和openssl生成RSA公钥私钥和证书,

    RSA公钥私钥证书,使用keytool和openssl生成 生成JKS文件命令 用kes文件 生成公钥和证书命令 重中之中!!!!!! JKS文件 你不要打开 直接复制,挪到你用的位置,或者替换你之前 ...

  2. rsa1024 公钥c语言程序,两种方式生成RSA 公钥私钥

    两种方式-生成RSA256私钥公钥 两种方式生成私钥公钥 1.ssh-keygen 方式 生成加密长度4096位密钥 生成私钥:ssh-keygen -t rsa -b 4096 -f ${priva ...

  3. java中使用openssl生成的rsa公私钥进行数据加解密_使用openssl生成RSA公钥和私钥对...

    在ubuntu上要使用openssl的话需要先进行安装,命令如下: sudo apt-get install openssl 安装完成就可以使用openssl了. 首先需要进入openssl的交互界面 ...

  4. 如何使用openssl生成RSA公钥和私钥对

    公私玥可使用OPENSSL工具生成. 在Windows环境下,可自行下载OPENSSL工具( http://www.openssl.org/related/binaries.html). 在Linux ...

  5. rsa公钥私钥生成工具

    rsa公钥私钥生成工具-java代码如下: /*** * @Description: RSA工具类,支持长度为2048的秘钥*/ @Slf4j public class RSAUtils {/*** ...

  6. C# RSA 公钥私钥生成方法

    生成C# RSA公钥私钥,上码: public sealed class RSAFromPkcs8{ /// <summary>/// 生成公钥与私钥方法/// </summary& ...

  7. 妙借Git自带的OpenSSL生成RSA公私钥的.pem 文件

    大家好,我是神韵,是一个技术&生活博主.出文章目的主要是两个,一是好记忆不如烂笔头,记录总结中提高自己.二是希望我的文章可以帮到大家.欢迎来点赞打卡,你们的行动将是我无限的动力. 本篇主题是: ...

  8. Java(111):非对称加密RSA的使用(openssl生成RSA公私钥对)

    Java(111):非对称加密RSA的使用(openssl生成RSA公私钥对) 1.openssl生成RSA公私钥对 [root@loaclhost ~]# openssl version OpenS ...

  9. js实现在线RSA公钥私钥对生成,加密/解密

    具体参考:在线RSA密钥生成,加密解密

最新文章

  1. c/c++内存机制(一)(原)
  2. 赋能 打造应对不确定性的敏捷团队 pdf_《赋能》:麦克里斯特尔教你打造应对不确定性的敏捷团队...
  3. 【Python初学者】准备
  4. 学习Java需要用到什么软件?
  5. boost::geometry::append用法的测试程序
  6. jmeter聚合报告如何添加单位_JMeter聚合报告(Aggregate Report)理解
  7. 陈述、叙述、表述、描述的区别
  8. (十)Linux之等待队列
  9. Window10 NVIDIA显卡 Tensorflow 2.1 GPU 安装和测试
  10. python中dtypes_Dataframe创建及index,columns,values,dtypes等属性介绍
  11. C#重写WebBrowser组件,禁止跳转到IE新窗口、脚本错误
  12. 升级到jdk1.8后 sun/io/CharToByteConverter错误及处理
  13. BZOJ1086 [SCOI2005]王室联邦(树分块)
  14. python获取文件修改时间_Python-获取文件最后修改时间 | 学步园
  15. c mysql主从复制_Mysql 主从复制
  16. AVOD阅读笔记(一):摘要+特征提取----Aggregate View Obeject Detection network
  17. centos8干净卸载mysql
  18. 计算机联锁控制台操作演示,车站计算机联锁控制台的设计.doc
  19. OceanBase分区表使用
  20. Emacs-hacking第三天

热门文章

  1. 能用机器完成的,千万别堆工作量|持续集成中的性能自动化测试
  2. 区块链应用@纸贵科技:基于阿里云容器服务护航内容版权
  3. 三款新功能发布,助力阿里云表格存储再次升级
  4. VMware vSphere 6.7主机与虚拟机高级管理
  5. 如何选择python书籍_关于 Python 的经典入门书籍有哪些?
  6. 分布式6大核心专题_分布式ID
  7. 项目管理过程组和知识领域 简介重点记忆
  8. 关于java的取整/和取余%
  9. Cannot obtain primary key information from the database, generated objects may be incomplete
  10. linux 环境 安装nginx