NodeJS 14+ 基于tls原生包实现RC4-MD5及自定义加密算法的方法
NodeJS TLS兼容旧设备及自定义加密方案
一、RC4-MD5算法适配实现
Node 14默认将TLS最小版本设为1.2,且OpenSSL安全级别默认禁用所有弱加密套件,因此直接指定RC4-MD5会报 cipher match 错误,按以下步骤修改即可适配:
1. 调整TLS配置项
修改你的TLS初始化参数,新增安全级别、最低TLS版本兼容配置:
const tls = require('tls'); const crypto = require('crypto'); const fs = require('fs'); const path = require('path'); let tlsOpts = { key: fs.readFileSync(path.resolve('dist/assets/cert/privkey.pem')), cert: fs.readFileSync(path.resolve('dist/assets/cert/cert.pem')), rejectUnauthorized: false, // 核心配置:安全级别设为0允许弱加密套件,明确指定RC4-MD5 ciphers: 'RC4-MD5:@SECLEVEL=0', // 兼容旧设备支持的TLS 1.0版本 minVersion: 'TLSv1', // 兼容旧设备TLS协商异常问题 secureOptions: crypto.constants.SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION | crypto.constants.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS }; this.server = tls.createServer(tlsOpts, async (socket) => { socket.setEncoding('utf8'); this.events(socket); }).listen(this.config.get('TCP_PORT'), () => { this.logger.log('TCP server started (port '+this.config.get('TCP_PORT')+')'); });
2. 调整NestJS启动参数
修改package.json中的启动脚本,新增Node运行参数强制允许弱加密套件:
{ "scripts": { "start": "node --tls-min-version=TLSv1 --tls-cipher-list=\"RC4-MD5:@SECLEVEL=0\" dist/main", "start:dev": "nest start --exec \"node --tls-min-version=TLSv1 --tls-cipher-list='RC4-MD5:@SECLEVEL=0'\"" } }
安全提示:RC4-MD5属于已被破解的弱加密算法,仅可在隔离的私有局域网场景下使用,禁止对公网暴露相关服务。
二、自定义加密算法在Node TLS中使用方案
Node的TLS模块基于OpenSSL实现,本身不支持直接通过配置ciphers参数使用非OpenSSL内置的加密算法,有两种实现路径可选:
方案1:流包裹方案(轻量,无需C开发)
不修改TLS底层逻辑,在原始TCP socket和业务逻辑之间插入自定义加解密流,实现自定义加密逻辑:
const net = require('net'); const { Transform } = require('stream'); // 自定义加解密流实现 class CustomCipherStream extends Transform { constructor(key, iv) { super(); this.key = key; this.iv = iv; } _transform(chunk, encoding, callback) { // 此处实现My-Custom-Cipher的加解密逻辑 const processed = this.customCipherEncryptDecrypt(chunk); this.push(processed); callback(); } customCipherEncryptDecrypt(chunk) { // 你的自定义算法实现逻辑 return chunk; } } // 替换原有TLS服务为TCP服务,嵌套自定义加密和TLS逻辑 this.server = net.createServer((rawSocket) => { // 初始化自定义加解密流 const cipherStream = new CustomCipherStream('你的密钥', '你的IV'); // 拼接流:原始socket <-> 自定义加密流 <-> TLS协商层 const tlsSocket = new tls.TLSSocket(cipherStream, { isServer: true, key: fs.readFileSync(path.resolve('dist/assets/cert/privkey.pem')), cert: fs.readFileSync(path.resolve('dist/assets/cert/cert.pem')), rejectUnauthorized: false }); tlsSocket.setEncoding('utf8'); this.events(tlsSocket); }).listen(this.config.get('TCP_PORT'), () => { this.logger.log('TCP server started with custom cipher (port '+this.config.get('TCP_PORT')+')'); });
方案2:OpenSSL引擎扩展(符合TLS标准,需C开发)
如果需要完全符合TLS协议规范,可通过扩展OpenSSL引擎的方式实现,步骤如下:
- 用C/C++开发OpenSSL引擎模块,实现自定义加密算法逻辑,注册对应的密码套件ID和名称
- 编译引擎为动态链接库文件
- 启动Node进程时配置环境变量加载自定义引擎:
OPENSSL_ENGINES=/path/to/your/engine node dist/main.js - 此时即可直接在TLS配置的
ciphers字段填写你注册的自定义加密套件名称。
安全提示:自定义加密算法需经过专业密码学审计,未经验证的自定义算法存在极大的安全漏洞风险,不建议在生产环境使用。
内容的提问来源于stack exchange,提问作者Zatrof
相关产品推荐
相关产品推荐

