Skip to content

第一百七十一章:内核加密

渡劫期

涉及内核源码:

离开 Spectre 和 Meltdown 的领地,林小源走进一片幽暗的密室。密室四壁镶嵌着无数锁孔,每个锁孔旁都刻着不同的符号——AES、SHA256、GCM、RSA。

一个身披银色铠甲的修士从阴影中走出,铠甲上流动着密文的纹路。

"crypto API,"修士自我介绍,声音清晰而有条理,"内核的加密框架。你看到的这些锁孔,每一个都是一种加密算法。"

林小源走近细看。左边一排是对称加密——AES、AES-256,一把钥匙同时用于加密和解密。中间是哈希——SHA256,单向计算,无法逆推。右边是认证加密——GCM,既加密又验证完整性。

"这么多算法,怎么选?"

crypto API 拍了拍铠甲上的纹路:"不用你选。你只需要调用统一的接口,告诉我你要做什么——加密、哈希、还是认证。我会根据你的硬件和需求,自动选择最优的实现。如果 CPU 支持 AES-NI 硬件加速,我就用硬件;没有的话,用软件实现。"

他伸手从墙上取下一个锁孔,注入一段密钥,锁孔便化作一个旋转的光轮,将林小源面前的一段明文吞入,吐出一串密文。

c
/*
 * 内核 crypto API:
 *
 * 算法类型:
 *   cipher — 对称加密 (AES, DES)
 *   hash — 哈希 (SHA256, MD5)
 *   aead — 认证加密 (GCM, CCM)
 *   skcipher — 对称分组加密
 *   akcipher — 非对称加密 (RSA)
 *   kdf — 密钥派生函数
 *
 * 使用方式:
 *   1. 分配算法
 *      crypto_alloc_skcipher("aes", 0, 0)
 *
 *   2. 设置密钥
 *      crypto_skcipher_setkey(tfm, key, keylen)
 *
 *   3. 加密/解密
 *      crypto_skcipher_encrypt(req)
 *      crypto_skcipher_decrypt(req)
 *
 * 应用场景:
 *   dm-crypt — 磁盘加密
 *   IPsec — 网络加密
 *   TLS — 传输加密
 *   dm-verity — 完整性验证
 */

/* 模拟加密算法 */
struct crypto_alg {
    const char *name;
    const char *type;
    int keysize;
    int blocksize;
};

struct crypto_alg algorithms[] = {
    {"aes", "skcipher", 16, 16},
    {"aes-256", "skcipher", 32, 16},
    {"sha256", "hash", 0, 32},
    {"hmac-sha256", "hash", 32, 32},
    {"gcm(aes)", "aead", 16, 16},
};

/* 模拟加密操作 */
void simulate_encrypt(const char *algo, const char *plaintext) {
    printf("  算法: %s\n", algo);
    printf("  明文: %s\n", plaintext);
    printf("  密文: [模拟加密结果]\n");
}

void simulate_hash(const char *algo, const char *data) {
    printf("  算法: %s\n", algo);
    printf("  数据: %s\n", data);
    printf("  哈希: [模拟哈希值]\n");
}

printf("=== 内核加密 — 保护数据 ===\n\n");

printf("内核 crypto API 提供加密功能:\n\n");

printf("--- 支持的算法 ---\n");
int n = sizeof(algorithms) / sizeof(algorithms[0]);
for (int i = 0; i < n; i++) {
    printf("%s:\n", algorithms[i].name);
    printf("  类型: %s\n", algorithms[i].type);
    if (algorithms[i].keysize)
        printf("  密钥长度: %d 字节\n", algorithms[i].keysize);
    printf("  块大小: %d 字节\n", algorithms[i].blocksize);
}

printf("\n--- 加密操作 ---\n");
simulate_encrypt("aes-256", "Hello, World!");

printf("\n--- 哈希操作 ---\n");
simulate_hash("sha256", "Hello, World!");

printf("\n--- 应用场景 ---\n");
printf("dm-crypt (磁盘加密):\n");
printf("  加密整个磁盘\n");
printf("  LUKS 格式\n");
printf("  cryptsetup luksFormat\n\n");
printf("IPsec (网络加密):\n");
printf("  加密网络流量\n");
printf("  ESP/AH 协议\n\n");
printf("TLS (传输加密):\n");
printf("  kTLS — 内核 TLS\n");
printf("  减少用户空间开销\n\n");
printf("dm-verity (完整性):\n");
printf("  验证磁盘数据\n");
printf("  防止篡改\n\n");

printf("--- 查看支持的算法 ---\n");
printf("cat /proc/crypto\n");

密室深处,林小源看到一扇厚重的铁门,门上刻着 "dm-crypt" 三个字。

"磁盘加密,"crypto API 站在门旁,"整个磁盘的数据都被加密。即使硬盘被人拔走,没有密钥就是一堆乱码。LUKS 格式,cryptsetup 工具——上层用起来很简单,底层全靠我的加密算法在撑。"

林小源推开门,看到铁门背后是一个巨大的保险库。库中堆满了加密后的数据块,每一块都经过 AES-256 加密,密钥由 keyring 子系统保管。

"密钥存在哪里?"他问。

"这就是另一个故事了,"crypto API 指向密室更深处的一道门,"keyring。密钥的安全和加密算法的安全同样重要。算法再强,密钥泄漏了,一切都是白费。"

林小源注意到密室的角落里还有一个小房间,门上写着 "kTLS"。

"内核态 TLS,"crypto API 说,"把 TLS 加密从用户空间移到内核。减少上下文切换,提高吞吐量。对高并发的 Web 服务器特别有用。"

林小源离开密室时,回头看了一眼那些闪烁的锁孔。每一个锁孔背后都是一种数学难题——AES 基于置换-置换网络,RSA 基于大数分解,SHA256 基于压缩函数。

"加密的本质,"他低声说,"是用数学的复杂度来换取时间。破解需要的时间越长,数据就越安全。"

crypto API 的声音从密室深处传来:"所以密钥长度很重要。128 位的 AES,暴力破解需要 2 的 128 次方次运算——宇宙毁灭了也解不完。但如果你用了弱密钥或者密钥泄漏了,再强的算法也没用。"

林小源点点头。加密是护盾,但护盾的强度取决于最弱的环节——往往不是算法本身,而是密钥管理、随机数生成、或者实现中的侧信道泄漏。

他继续向前走去。密室的门在身后缓缓关闭,锁孔的光芒在黑暗中渐渐远去。


道藏笔记

内核启示

内核的 crypto API 是个统一的加密框架。你不用管底层用的是 AES-NI 硬件加速还是软件实现,只需要告诉它你要加密、哈希还是认证,它自动选最优的。算法类型有对称加密(AES)、哈希(SHA256)、认证加密(GCM)、非对称加密(RSA)等。

到处都在用它:dm-crypt 加密整个磁盘(LUKS 格式),IPsec 加密网络流量,kTLS 把 TLS 加密搬到内核态减少上下文切换,dm-verity 用哈希验证磁盘数据完整性。加密的本质是用数学复杂度换时间——AES-128 暴力破解要 2 的 128 次方次运算。但算法再强,密钥泄漏了一切白费。

crypto 是护盾——保护数据不被窃取。


破关试炼

内核加密之试

内核加密一章中,正文举出的对称加密算法代表是什么?

答对后才能继续滑动和进入下一章。

以修仙之名,悟内核之道