hejunjie/encrypted-request 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

hejunjie/encrypted-request

Composer 安装命令:

composer require hejunjie/encrypted-request

包简介

PHP 请求加密工具包,支持 AES 解密、签名与时间戳验证,快速实现前后端安全通信 | PHP encryption toolkit for AES decryption, signature, and timestamp verification, enabling fast and secure front-to-backend communication. Front-end npm package generates encrypted request parameters without changing existing APIs

README 文档

README

English简体中文

A PHP encryption toolkit for secure front-end to back-end communication.

In real-world development, API endpoints often require security: data needs encryption to prevent sniffing, and requests must be protected from tampering and replay attacks. Coordinating encryption methods and signature rules with the front-end can be tedious. This package, paired with the front-end npm package, lets the front-end generate encrypted request parameters with a single call, while the back-end decrypts and verifies in just a few lines of code.

Front-end companion npm package: npm-encrypted-request

This project has been parsed by Zread. Click to learn more: Learn More

Features

  • 🔐 Hybrid encryption: AES-256-GCM symmetric encryption + RSA-OAEP asymmetric encryption. AES keys are randomly generated by the front-end and transmitted via RSA public key encryption — the back-end only needs the RSA private key
  • ✍️ HMAC-SHA256 signature verification: Prevents request parameters from being tampered with
  • Timestamp validation: Second-level verification with configurable tolerance to prevent request replay
  • 🔑 Nonce anti-replay: One-time random number mechanism to block duplicate requests
  • ⚙️ Flexible configuration: Supports .env files, inline arrays, or custom .env paths
  • 🧩 Extensible: Pluggable Nonce validator (Redis, APCu, etc.) for production environments

Installation

composer require hejunjie/encrypted-request

Quick Start

1. Configuration

Via .env file:

RSA_PRIVATE_KEY=your-private-key
SIGN_SECRET=your-sign-secret
DEFAULT_TIMESTAMP_DIFF=60
NONCE_TTL=300

Or via an array:

$config = [
    'RSA_PRIVATE_KEY'       => 'your-private-key',   // RSA private key (including -----BEGIN PRIVATE KEY-----)
    'SIGN_SECRET'            => 'your-sign-secret',   // HMAC-SHA256 signing key
    'DEFAULT_TIMESTAMP_DIFF' => 60,                   // Timestamp tolerance in seconds, default 60
    'NONCE_TTL'              => 300,                  // Nonce TTL in seconds, default 300
];

2. Decrypt Requests

use Hejunjie\EncryptedRequest\EncryptedRequestHandler;
use Hejunjie\EncryptedRequest\Contracts\NonceValidatorInterface;

$params = $_POST; // Obtain front-end request parameters

// EncryptedRequestHandler constructor:
//   __construct(array|string $config = '', int $protocolVersion = 1, ?NonceValidatorInterface $nonceValidator = null)
//
// - First argument: config array, .env file path, or omit (auto-detect .env)
// - Second argument: Protocol version — defaults to 1
// - Third argument: Nonce validator — defaults to in-memory implementation (testing only!)

$handler = new EncryptedRequestHandler($config);  // Omit first argument if using .env

try {
    $data = $handler->handle(
        $params['en_data'] ?? '',
        $params['enc_payload'] ?? '',
        (int)($params['timestamp'] ?? 0),
        $params['sign'] ?? ''
    );
    // $data is the decrypted array
} catch (\Hejunjie\EncryptedRequest\Exceptions\SignatureException $e) {
    // Invalid signature
} catch (\Hejunjie\EncryptedRequest\Exceptions\TimestampException $e) {
    // Timestamp out of range
} catch (\Hejunjie\EncryptedRequest\Exceptions\NonceException $e) {
    // Nonce already used (replay attack)
} catch (\Hejunjie\EncryptedRequest\Exceptions\DecryptionException $e) {
    // RSA or AES decryption failed
}

Warning

Without the third argument, the default InMemoryNonceValidator stores nonces in process memory, which is lost after each PHP request — it cannot truly prevent replay attacks. Always pass a custom Nonce validator in production. See the "Custom Nonce Validator" section below.

Configuration Reference

Config Type Required Default Description
RSA_PRIVATE_KEY string - RSA private key for decrypting the AES key from the front-end
SIGN_SECRET string - HMAC-SHA256 signing key, must match the front-end
DEFAULT_TIMESTAMP_DIFF int 60 Timestamp tolerance in seconds
NONCE_TTL int 300 Nonce time-to-live in seconds

How It Works

Signature Verification → Timestamp Check → RSA Decrypt (AES Key) → Nonce Anti-Replay → AES-256-GCM Decrypt
  1. Signature verification (runs first): HMAC-SHA256 over en_data + enc_payload + timestamp using SIGN_SECRET. Invalid requests are rejected immediately.
  2. Timestamp check: Ensures the request timestamp is within the configured tolerance.
  3. RSA decryption: Decrypts enc_payload with the RSA private key to obtain the AES key, IV, and Nonce.
  4. Nonce verification: Checks whether the Nonce has been used before, preventing replay attacks.
  5. AES-256-GCM decryption: Decrypts the request data using the extracted AES key and IV.

Front-End Integration

The front-end uses the hejunjie-encrypted-request npm package to generate encrypted data:

import { encryptRequest, EncryptOptions } from "hejunjie-encrypted-request";

const options: EncryptOptions = {
    data: { message: "Hello" },
    rsaPublicKey: pubKey,
    signSecret: signSecret,
};

const payload = await encryptRequest(options, version);

The PHP back-end can then decrypt directly using EncryptedRequestHandler.

Custom Nonce Validator

The default InMemoryNonceValidator stores nonces in process memory and is only suitable for single-process or testing environments. For production, implement the NonceValidatorInterface (e.g., with Redis, APCu, or a database) and pass it as the third argument to the EncryptedRequestHandler constructor:

use Hejunjie\EncryptedRequest\EncryptedRequestHandler;
use Hejunjie\EncryptedRequest\Contracts\NonceValidatorInterface;

// 1. Implement NonceValidatorInterface
class RedisNonceValidator implements NonceValidatorInterface
{
    private \Redis $redis;

    public function __construct(\Redis $redis)
    {
        $this->redis = $redis;
    }

    public function verify(string $nonce, int $ttl): bool
    {
        // Use SET NX EX for atomic check-and-set
        return $this->redis->set("nonce:{$nonce}", 1, ['nx', 'ex' => $ttl]) === true;
    }
}

// 2. Inject as the third argument (using named parameter)
$handler = new EncryptedRequestHandler(
    $config,                                    // First argument: config
    nonceValidator: new RedisNonceValidator($redis)  // Third argument: custom Nonce validator
);

Directory Structure

src/
├── Config/
│   └── EnvConfigLoader.php          # Configuration loader (.env + array)
├── Contracts/
│   ├── DecryptorInterface.php       # Decryptor interface
│   └── NonceValidatorInterface.php  # Nonce validator interface
├── Drivers/
│   ├── AesDecryptor.php             # AES-256-GCM decryptor
│   ├── InMemoryNonceValidator.php   # In-memory Nonce validator (default, testing only)
│   └── RsaDecryptor.php             # RSA-OAEP decryptor
├── Exceptions/
│   ├── DecryptionException.php      # Decryption exception
│   ├── NonceException.php           # Nonce exception (replay attack)
│   ├── SignatureException.php       # Signature exception
│   └── TimestampException.php       # Timestamp exception
└── EncryptedRequestHandler.php      # Core handler

Compatibility

  • PHP >= 8.0
  • Requires PHP OpenSSL extension
  • Works with any PSR-4 autoloading framework or vanilla PHP project

FAQ

Is the default Nonce validator suitable for production?

No. InMemoryNonceValidator stores data in process memory, which is lost after each PHP request — it cannot reliably prevent replay attacks. For production, inject a Redis or database-backed implementation as shown in the "Custom Nonce Validator" section above.

How do I keep the signing key consistent between front-end and back-end?

The SIGN_SECRET value must exactly match the signSecret parameter passed to encryptRequest() on the front-end. Store the key in .env and sync it to the front-end through a secure channel.

Which PHP frameworks are supported?

Any project following PSR-4 autoloading, including but not limited to Laravel, Symfony, Slim, ThinkPHP, and plain PHP projects.

Contributing

Issues and pull requests are welcome.

hejunjie/encrypted-request 适用场景与选型建议

hejunjie/encrypted-request 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 240 次下载、GitHub Stars 达 1, 最近一次更新时间为 2025 年 08 月 26 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 hejunjie/encrypted-request 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 hejunjie/encrypted-request 我们能提供哪些服务?
定制开发 / 二次开发

基于 hejunjie/encrypted-request 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 240
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 33
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-08-26