动态

详情 返回 返回

RSA+AES 混合加密不復雜,但落地挺煩,我用 Vue+PHP 封裝成了兩個庫 - 动态 详情

在項目裏寫接口的時候,我有時候會希望再多一層保護
雖然 HTTPS 已經能保證傳輸安全,但它解決的更多是「傳輸過程中不被竊聽/篡改」的問題。
而我還想順帶做到幾點:

  • 防止接口被隨便模擬調用
  • 就算數據包被截獲,也看不懂內容
  • 就算有人拿着同一份請求去重放,服務端也能拒絕

這些需求其實挺常見的,但並不複雜,説白了就是一套 RSA+AES 混合加密


經典的思路

原理本身沒什麼新鮮的:

  • 每次請求生成一個隨機 AES Key
  • 用 AES 加密數據
  • 再用 RSA 公鑰把 AES Key 加密後傳給後端
  • 後端用 RSA 私鑰解密出 AES Key,再還原請求體

這是標準做法,網上能搜到很多講解。


真正麻煩的地方

難點其實不在原理,而是在項目裏真正用的時候。

比如要自己實現,就得寫:

  • 每次生成隨機 AES Key
  • RSA 公鑰加密 AES Key
  • AES 加密/解密請求體
  • 簽名計算、時間戳校驗,避免重放
  • 各種異常處理(簽名錯、時間戳過期、解密失敗)

單看每一塊都不復雜,但組合在一起就有點煩。
而且這些邏輯和業務關係不大,卻不得不散落在代碼裏。


我做的小工具

為了省事,我乾脆把它們封裝成了前後端兩個庫:

  • 前端是一個 npm 包
  • 後端是一個 PHP 的 Composer 庫

目標就是:用起來跟普通請求沒什麼兩樣,但底層自動幫你做了加解密和校驗


用法示例

前端:

npm install hejunjie-encrypted-request
import { encryptRequest } from "hejunjie-encrypted-request";

# 不建議在代碼裏寫死公鑰,建議通過讀取文件來獲取公鑰字符串
const encrypted = encryptRequest({ name: "張三" }, {
  publicKey: "-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----",
});

request.post("/api/user/info", encrypted)
  .then(res => console.log(res));

後端:

composer require hejunjie/encrypted-request
use Hejunjie\EncryptedRequest\EncryptedRequestHandler;

// 自行在中間件或方法前完成請求參數的獲取
$param = $_POST;

// 同樣不建議代碼裏寫死私鑰
// 要麼私鑰作為 RSA_PRIVATE_KEY 放在.env裏(此方法就無需再傳遞$config)
// 要麼直接讀取文件作為配置傳遞
$config = [
    'RSA_PRIVATE_KEY' => file_get_contents(private_key.pem)
];
$handler = new EncryptedRequestHandler($config);
$data = $encrypted->handle($param['en_data'] ?? '', $param['enc_payload'] ?? '', $param['timestamp'] ?? '', $param['sign'] ?? '');

print_r($data); // ['name' => '張三']

開發者只需要像平時一樣寫請求,庫會自動處理 AES/RSA 加解密、簽名、時間戳校驗、異常。


適合的場景

這個方案當然不是替代 HTTPS,而是作為額外的一層保護

  • 內部系統,不希望接口被隨便重放/模擬
  • 中小項目,對安全有點額外要求,但不想上很重的安全框架
  • 想快速把 RSA+AES 混合加密落地,而不用自己重複造輪子

倉庫地址

  • 前端倉庫:npm-encrypted-request
  • 後端倉庫:php-encrypted-request

希望能幫到和我一樣遇到類似需求的人。

user avatar soroqer 头像 big_cat 头像 bytebase 头像 syntaxerror 头像 euphoria 头像 hanhoudeniupai 头像
点赞 6 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.