OpenSSL 作為業界標準密碼庫,提供了豐富的內建算法,但特定合規或專有場景下需集成自定義算法。本文以添加國密算法 EVP_ssf33 (基於 RC4 封裝) 為例,完整演示從 OID 註冊、源碼編輯、構建系統修改到動態引擎加載的全流程。
# 安裝 OpenSSL 源碼構建依賴
# RHEL/CentOS
yum install perl gcc make zlib-devel
# Debian/Ubuntu
apt-get install build-essential libssl-dev
# 獲取 OpenSSL 源碼 (與目標版本一致)
wget https://www.openssl.org/source/openssl-3.0.13.tar.gz
tar xzf openssl-3.0.13.tar.gz
cd openssl-3.0.13
編輯 crypto/objects/objects.txt,在合適位置添加:
# Algorithm OIDs
# rsadsi (1.2.840.113549) -> 3 (SSF33)
rsadsi 3 255 : SSF33 : ssf33
rsadsi:父節點短名 (1.2.840.113549)。3 255:對應 OID 1.2.840.113549.3.255。SSF33:長名,ssf33:短名 (用於代碼引用)。cd crypto/objects
perl objects.pl objects.txt obj_mac.num obj_mac.h
# 生成 obj_mac.h (含 NID_ssf33 定義) 與 obj_mac.num (數值映射)
在 crypto/evp/ 下創建 e_ssf33.c:
#include
#include "cryptlib.h"
#ifndef OPENSSL_NO_RC4
#include
#include
#include
#define EVP_SSF33_KEY_SIZE 16
typedef struct {
RC4_KEY ks;
} EVP_SSF33_KEY;
#define DATA(ctx) ((EVP_SSF33_KEY *)(ctx)->cipher_data)
static int ssf33_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc);
static int ssf33_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, unsigned int inl);
static const EVP_CIPHER ssf33_evp_cipher = {
NID_ssf33, // NID
1, // block_size (流密碼為 1)
EVP_SSF33_KEY_SIZE, // key_len
0, // iv_len (RC4 無 IV)
EVP_CIPH_VARIABLE_LENGTH, // flags
ssf33_init_key,
ssf33_cipher,
NULL, // cleanup
sizeof(EVP_SSF33_KEY), // ctx_size
NULL, NULL, NULL, NULL, NULL
};
const EVP_CIPHER *EVP_ssf33(void) {
return &ssf33_evp_cipher;
}
static int ssf33_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc) {
RC4_set_key(&DATA(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key);
return 1;
}
static int ssf33_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, unsigned int inl) {
RC4(&DATA(ctx)->ks, inl, in, out);
return 1;
}
#endif
編輯 crypto/evp/build.info (OpenSSL 3.x) 或 Makefile (1.1.1),添加:
# build.info
SOURCE[e_ssf33.c]
並確保 crypto/evp/evp.h 或對應頭文件聲明 const EVP_CIPHER *EVP_ssf33(void);。
./config --prefix=/usr/local/ssl-custom shared
make -j$(nproc)
make install_sw # 僅安裝軟件,不覆蓋系統文檔
export LD_LIBRARY_PATH=/usr/local/ssl-custom/lib64:$LD_LIBRARY_PATH
openssl ciphers -v | grep -i ssf33
# 應輸出類似:SSF33 SSLv3 Kx=RSA Au=RSA Enc=SSF33(128) Mac=SHA1
# 加密測試
echo "test data" | openssl enc -ssf33 -K 0123456789abcdef0123456789abcdef -nosalt -out /tmp/enc.bin
openssl enc -d -ssf33 -K 0123456789abcdef0123456789abcdef -nosalt -in /tmp/enc.bin
# 輸出 "test data"
#include
#include
#include
int main() {
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
const EVP_CIPHER *cipher = EVP_ssf33();
unsigned char key[16] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
unsigned char in[] = "Hello SSF33";
unsigned char out[32];
int outl, tmpl;
EVP_EncryptInit_ex(ctx, cipher, NULL, key, NULL);
EVP_EncryptUpdate(ctx, out, &outl, in, strlen((char*)in));
EVP_EncryptFinal_ex(ctx, out+outl, &tmpl);
outl += tmpl;
printf("Ciphertext len: %d\n", outl);
EVP_CIPHER_CTX_free(ctx);
return 0;
}
編譯:gcc test_ssf33.c -o test_ssf33 -I/usr/local/ssl-custom/include -L/usr/local/ssl-custom/lib64 -lssl -lcrypto -Wl,-rpath,/usr/local/ssl-custom/lib64
生產環境推薦編寫 OpenSSL ENGINE 動態庫,運行時加載,避免替換系統 OpenSSL 帶來的兼容風險。
#include
#include
extern const EVP_CIPHER *EVP_ssf33(void);
static int ssf33_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
const int **nids, int nid) {
if (!cipher) { *nids = (int[]){NID_ssf33, 0}; return 1; }
if (nid == NID_ssf33) { *cipher = EVP_ssf33(); return 1; }
return 0;
}
static const ENGINE_CMD_DEFN ssf33_cmd_defns[] = {{NULL, NULL, NULL, 0}};
int bind_ssf33(ENGINE *e) {
if (!ENGINE_set_id(e, "ssf33") ||
!ENGINE_set_name(e, "Custom SSF33 Engine") ||
!ENGINE_set_ciphers(e, ssf33_ciphers) ||
!ENGINE_set_cmd_defns(e, ssf33_cmd_defns))
return 0;
return 1;
}
IMPLEMENT_DYNAMIC_CHECK_FN()
IMPLEMENT_DYNAMIC_BIND_FN(bind_ssf33)
gcc -fPIC -shared -o libssf33_engine.so engine_ssf33.c e_ssf33.c \
-I/usr/local/ssl-custom/include -L/usr/local/ssl-custom/lib64 -lcrypto
# openssl.cnf 添加
[engine_section]
ssf33 = ssf33_section
[ssf33_section]
engine_id = ssf33
dynamic_path = /path/to/libssf33_engine.so
default_algorithms = CIPHERS
# 環境變量指定配置
OPENSSL_CONF=/path/to/openssl.cnf openssl ciphers -v | grep SSF33

objects.txt + objects.pl。e_alg.c + build.info。./config && make && make install_sw。openssl enc -alg / 應用調用 EVP_alg()。掌握此流程,您將具備為 OpenSSL 定制專屬密碼原語的能力,滿足國密合規、專有協議、學術研究等多元化需求。
Linux 設定 .NET IIS 中繼資料庫讀取權限:aspnet_regiis -i 一鍵修復
chown 變更檔案擁有者與群組:語法、遞迴、參考檔、僅變更符合條件、管理員權限、實戰範例
Fedora 18 安裝 arping 步驟:解決 libnet-devel、libpcap-devel 依賴
Linux 記憶體耗盡排查實戰:top 發現佔用高、vmstat -m 定位 xfs_inode 洩漏
Ubuntu Vim 打造 Source Insight 體驗:ctags + cscope 完整安裝與配置指南
Linux 進程排程算法深度解析:FCFS、RR、多級回饋佇列、實時排程與 CFS 完全公平排程器