最佳方式不是硬改 php-src 内核代码,而是写一个 PHP 扩展(C 扩展)把算法嵌进去。 这样升级oPHPu版本时成本最低、最稳、可回滚。 --- 先说大白话架构 你要“底层嵌入”,有3条路:1. 改 php-src 源码(最不推荐) - 每次升级 PHP 都要重打补丁,维护地狱。2. 写普通 PHP 扩展(推荐) - 算法在 C 里,PHP 层只调用 my_encrypt()/ my_decrypt()。 - 性能高,部署简单,版本升级可控。3. 写 Zend 扩展做全局 Hook(仅特殊场景) - 复杂度高,除非你要强制拦截所有加解密调用。 所以最佳方式:普通 C 扩展 + 自研算法内核化实现 + 密钥管理外置。 --- 关键原则(非常重要) - 自研算法只建议用于“业务协议/混淆/特定合规”,不要替代标准密码学(TLS、存储加密仍用 AES-GCM/ChaCha20-Poly1305)。 - 密钥不要写死在代码里,放 KMS/HSM/环境变量。 - 算法接口要带版本号,后续可平滑升级算法。 --- 完整代码(可编译的扩展模板) 下面给你一套完整最小可运行版本,算法示例用“XOR+轮转”(演示嵌入方法,不是强密码算法)。 ---1)config.m4 PHP_ARG_ENABLE(mycrypto, whether toenablemycrypto extension,[--enable-mycrypto Enable mycrypto extension], no)iftest"$PHP_MYCRYPTO"!="no";thenPHP_NEW_EXTENSION(mycrypto, mycrypto.c,$ext_shared)fi---2)php_mycrypto.h#ifndef PHP_MYCRYPTO_H#define PHP_MYCRYPTO_Hextern zend_module_entry mycrypto_module_entry;#define phpext_mycrypto_ptr &mycrypto_module_entry#define PHP_MYCRYPTO_VERSION "0.1.0"PHP_FUNCTION(mycrypto_encrypt);PHP_FUNCTION(mycrypto_decrypt);#endif---3)mycrypto.c#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "php.h"#include "php_mycrypto.h"#include "ext/standard/info.h"ZEND_BEGIN_ARG_INFO_EX(arginfo_mycrypto_encrypt,0,0,2)ZEND_ARG_TYPE_INFO(0, plaintext, IS_STRING,0)ZEND_ARG_TYPE_INFO(0, key, IS_STRING,0)ZEND_END_ARG_INFO()ZEND_BEGIN_ARG_INFO_EX(arginfo_mycrypto_decrypt,0,0,2)ZEND_ARG_TYPE_INFO(0, ciphertext_b64, IS_STRING,0)ZEND_ARG_TYPE_INFO(0, key, IS_STRING,0)ZEND_END_ARG_INFO()static inline unsigned char rotl8(unsigned char v, unsigned char n){return(unsigned char)((v<<(n&7))|(v>>(8-(n&7))));}static inline unsigned char rotr8(unsigned char v, unsigned char n){return(unsigned char)((v>>(n&7))|(v<<(8-(n&7))));}/* 示例算法:按 key 做 XOR + bit rotate(仅演示接口形态) */ static void mycrypto_transform_encrypt(unsigned char *buf, size_t len, const unsigned char *key, size_t klen){size_t i;for(i=0;i<len;i++){unsigned char kb=key[i % klen];buf[i]^=kb;buf[i]=rotl8(buf[i],(unsigned char)(kb&0x07));}}static void mycrypto_transform_decrypt(unsigned char *buf, size_t len, const unsigned char *key, size_t klen){size_t i;for(i=0;i<len;i++){unsigned char kb=key[i % klen];buf[i]=rotr8(buf[i],(unsigned char)(kb&0x07));buf[i]^=kb;}}PHP_FUNCTION(mycrypto_encrypt){zend_string *plaintext, *key;zend_string *tmp, *b64;ZEND_PARSE_PARAMETERS_START(2,2)Z_PARAM_STR(plaintext)Z_PARAM_STR(key)ZEND_PARSE_PARAMETERS_END();if(ZSTR_LEN(key)==0){zend_throw_error(NULL,"key must not be empty");RETURN_THROWS();}tmp=zend_string_init(ZSTR_VAL(plaintext), ZSTR_LEN(plaintext),0);mycrypto_transform_encrypt((unsigned char*)ZSTR_VAL(tmp),ZSTR_LEN(tmp),(const unsigned char*)ZSTR_VAL(key),ZSTR_LEN(key));b64=php_base64_encode((unsigned char*)ZSTR_VAL(tmp),ZSTR_LEN(tmp));zend_string_release(tmp);RETURN_STR(b64);}PHP_FUNCTION(mycrypto_decrypt){zend_string *ciphertext_b64, *key;zend_string *raw;zend_string *out;size_t raw_len=0;ZEND_PARSE_PARAMETERS_START(2,2)Z_PARAM_STR(ciphertext_b64)Z_PARAM_STR(key)ZEND_PARSE_PARAMETERS_END();if(ZSTR_LEN(key)==0){zend_throw_error(NULL,"key must not be empty");RETURN_THROWS();}raw=php_base64_decode((unsigned char*)ZSTR_VAL(ciphertext_b64),ZSTR_LEN(ciphertext_b64));if(!raw){zend_throw_error(NULL,"invalid base64 ciphertext");RETURN_THROWS();}raw_len=ZSTR_LEN(raw);out=zend_string_init(ZSTR_VAL(raw), raw_len,0);zend_string_release(raw);mycrypto_transform_decrypt((unsigned char*)ZSTR_VAL(out),ZSTR_LEN(out),(const unsigned char*)ZSTR_VAL(key),ZSTR_LEN(key));RETURN_STR(out);}PHP_MINFO_FUNCTION(mycrypto){php_info_print_table_start();php_info_print_table_header(2,"mycrypto support","enabled");php_info_print_table_row(2,"version", PHP_MYCRYPTO_VERSION);php_info_print_table_end();}static const zend_function_entry mycrypto_functions[]={PHP_FE(mycrypto_encrypt, arginfo_mycrypto_encrypt)PHP_FE(mycrypto_decrypt, arginfo_mycrypto_decrypt)PHP_FE_END};zend_module_entry mycrypto_module_entry={STANDARD_MODULE_HEADER,"mycrypto", mycrypto_functions, NULL, NULL, NULL, NULL, PHP_MINFO(mycrypto), PHP_MYCRYPTO_VERSION, STANDARD_MODULE_PROPERTIES};#ifdef COMPILE_DL_MYCRYPTO# ifdef ZTSZEND_TSRMLS_CACHE_DEFINE()# endifZEND_GET_MODULE(mycrypto)#endif--- 编译安装步骤 phpize ./configure --enable-mycryptomake-j"$(nproc)"makeinstall找到 mycrypto.so 后,在 php.ini 加:extension=mycrypto.so 验证: php-m|grepmycrypto php-r'echo mycrypto_encrypt("hello","k"), PHP_EOL;'--- PHP 调用示例<?php$key=getenv('APP_CRYPTO_KEY')?:'demo-key-please-change';$plain='order=12345&amount=88.66';$cipher=mycrypto_encrypt($plain,$key);$back=mycrypto_decrypt($cipher,$key);echo"cipher: {$cipher}\n";echo"plain : {$back}\n";--- 生产最佳方式(落地版)1. 扩展里保留算法 v1/v2,接口加 algo_version。2. 密钥走 KMS/HSM,不进代码仓库。3. 增加 MAC/Tag(完整性校验),别只“加密不验签”。4. CI 跑跨版本测试(PHP8.1/8.2/8.3)。5. 做灰度发布:先双写双解(新老算法并行)再切流量。 --- 最后一句: “内核嵌入”最优解是“扩展化实现 + 密钥外置 + 版本化演进”,不是长期维护 php-src 魔改分支。