当前位置: 首页 > news >正文

php电子签名

原理

使用一对公钥和私钥,用私钥对数据进行签名,用公钥对签名数据进行加密,形成电子签名。

电子签名认证,用私钥解密数据,用公钥验证签名。

若加密容过长,则将加密内容按照固定长度分块,对每块进行加密再拼接;解密时也是分块进行,

分割大小固定。

生成证书

# 生成私钥openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048# 生成公钥openssl rsa -pubout -in private_key.pem -out public_key.pem

代码

目录结构

- public_private_key 证书
---- private_key.pem 私钥
---- public_key.pem 公钥- src
-- esign.php 电子签名类- vendor 扩展包-index.php 调用文件

电子签名类

namespace Wj/Esign;class esign {const RSA_ENCRYPT_BLOCK_SIZE = 117; //加密切割长度const RSA_DECRYPT_BLOCK_SIZE = 256; //解密切割长度private $privateKey; //私钥证书private $publicKey; //公钥证书private $signstr; //加密数据 字符串public function __construct($signdata) {$path = ROOT_PATH . "public_private_key" . DS . DS;$this->privateKey = openssl_get_privatekey(file_get_contents($path . "private_key.pem"));$this->publicKey = openssl_get_publickey(file_get_contents($path . "public_key.pem"));$this->setsigndata($signdata);}private function setsigndata($signdata) {$signstr = $signdata;if (is_array($signdata)) {$signstr = implode("", $signdata);}if (!is_string($signstr)) {if (empty($signstr)) {throw new \Exception("加密数据错误");}}$this->signstr = $signstr;}/*** 获取签名*/public function getsignstr() {openssl_sign($this->signstr, $signature, $this->privateKey);$signature = base64_encode($signature);$data = $this->encryptsign($signature);return $data;}/*** 加密签名*/private function encryptsign($signature) {if (!is_string($signature)) {return null;}$signature_arr = str_split($signature, self::RSA_ENCRYPT_BLOCK_SIZE);$useencrypted = "";foreach ($signature_arr as $key => $block) {openssl_public_encrypt($block, $encrypted, $this->publicKey, OPENSSL_PKCS1_OAEP_PADDING);$useencrypted .= $encrypted;}$useencrypted = base64_encode($useencrypted);return $useencrypted ? $useencrypted : null;}/*** 解密签名*/private function decryptsign($encrypted) {if (!is_string($encrypted)) {return null;}$result = '';$encrypted_arr = str_split(base64_decode($encrypted), self::RSA_DECRYPT_BLOCK_SIZE);foreach ($encrypted_arr as $block) {openssl_private_decrypt($block, $dataDecrypt, $this->privateKey, OPENSSL_PKCS1_OAEP_PADDING);$result .= $dataDecrypt;}return $result ? $result : null;}/*** 签名验证*/public function verifysign($encrypted) {$encodestr = $this->decryptsign($encrypted);$result = base64_decode((string) $encodestr);$result = openssl_verify($this->signstr, $result, $this->publicKey);return $result == 1 ? true : false;}
}

调用

define('DS', DIRECTORY_SEPARATOR);
defined('ROOT_PATH') or define('ROOT_PATH', __DIR__ . DS);require "./vendor/autoload.php";
use Wj\Esign\esign;$data = ['name' => 'test','time' => time(),
];
$es = new esign($data);
$encrypted = $es->getsignstr();
$result = $es->verifysign($encrypted);
var_dump($encrypted, $result);

输出结果

string(1024) "g5j76cEr/odqfH6H4kUYM6GwCoJYKNLyh61O10XDIbCwqo0p+kmPhyMGL4sFam8L/vpCxwabV7FHjhq5JYbgYCq19T4PqsJ2yO8xs/Lf3x3DWvImIAkBghYRLYtyri6JoK2CATQ7cGWKYl9s16LLvpxmmLlcWztnvRc47NkjEVinTNKGghNLcSU1pmphCyvI0nzYMCdrsTKGWVPt5qDXUtJsukLS8rMfxQNQQppRUeETUr+1+r8PAEqrJVRSeJIQ+Eng/JpolWB4cYnLjOPqknU8ft4zuHGwcGbtcvk/DGI2B+4uwC+Y71evWim+Jct6hFE7IOQNIuUyg/gpAcQH7z3Ab6gfdup0pM4gfM/rCsfvMhC07AngeraiE+5Yzl2mugzzYe5hHZ5epUPpur3K/v1ZP3Hf6thzmImvcj1b661FB3ElVSLbqHl9SvrYgd5LQOfl0ThsJe51dJqp+40hmeH7jyYrJAtykmDIu992lsfkc+eJQ1NcyNnseztQ7f0F0vj2sLNnpR26PvXznik2auQPMLdsr3ksPbJM9gcaCPLE0apfbU0dUvGwpVGgbPYpRgSpGQXtc5uAeJtk/Ia24KMj7kOVlXG//3T7UhkrxF8WSmlfFoRpJq5jnc+ANNfZzRcINs3VdsTHHtWsbLjgCNsiPHAz9bezqs2y2JsFQMgJ6U+2QMQRwnSlEEQMtC9NCQJeTe3YivEhhEsgfNKLdS0+O8Ml3qRnYYLC0zI63EL6PsN7S69WQwS839TdtdUiwvUy8SC2rfYrXwNQpttCxJ/LQJTznOZbnYdMqTp2C0XRCMn8Jz5GQY4c3ZpP48MZ3+kAjKgNF1U9cWw0zDwEYIkFBI0EHAAYTgrRXNlUfSCgkDnKlb813WKrz/+f2oUQKYzl+wI25T4EREuASv3xi5Q/INlasL3Nj0jzLxwsHkm4hvon4aG2uc1oeNviPOmCgArKCNwQ+R4R8mvS1wTNnckgEdkFV9G0V6SxJUixIiKZAxSeaAL7Ijng6PGhJsFp"
D:\workspace\php\test\esign\index2.php:15:
bool(true)

http://www.dtcms.com/a/358676.html

相关文章:

  • 2025年09月计算机二级MySQL选择题每日一练——第十二期
  • Rust 登堂 之 Sized和不定长类型 DST(七)
  • LabVIEW 时间字符串处理与显示
  • 继电器的作用、选型和测量-超简单解读
  • 算法题(195):点名
  • 【学Python自动化】 2. Windows Python 解释器使用笔记
  • 【shell】Shell脚本中的if判断条件和文件测试操作符
  • “人工智能+”政策驱动下的技术重构、商业变革与实践路径研究 ——基于国务院《关于深入实施“人工智能+”行动的意见》的深度解读
  • STM32的内存分配与堆栈
  • Redis 测试:过期 key 内存释放情况
  • JVM架构图是怎样的?
  • 算法(④KMP)
  • SpringAI应用开发工程师高阶面试剧本与知识点全解析(含RAG、多租户、流式推理、企业落地场景)
  • Python3 lambda(匿名函数)
  • HBase高效并发锁:IdLock极简内存设计
  • Qt QML注册全局对象并调用其函数和属性
  • 银河麒麟Kylin系统编译安装Qt5.12.12
  • Yolov8损失函数:回顾Yolov8-Loss
  • ​导游|基于SprinBoot+vue的在线预约导游系统
  • DrissionPage 实战:高效爬取网页数据并保存为 CSV 的全流程解析
  • (链表)Leetcode206链表反转+Leetcode6删除链表的倒数第N个结点+虚拟头节点使用
  • Linux 笔记 Day01|课程结构
  • 第三弹、AI、LLM大模型是什么?
  • 深度学习重塑医疗:四大创新应用开启健康新纪元
  • MySQL-事务(上)
  • 【Linux】如何使用 Xshell 登录 Linux 操作系统
  • Linux 下 Docker 容器部署指南(Java + Redis 示例)
  • ⭐CVPR2025 自动驾驶半监督 LiDAR 分割新范式:HiLoTs 框架深度解析
  • 设置word引用zotero中的参考文献的格式为中文引用格式或中英文格式
  • Shell编程核心入门:参数传递、运算符与流程控制全解析