第一百七十一章:内核加密
渡劫期涉及内核源码:
一
离开 Spectre 和 Meltdown 的领地,林小源走进一片幽暗的密室。密室四壁镶嵌着无数锁孔,每个锁孔旁都刻着不同的符号——AES、SHA256、GCM、RSA。
一个身披银色铠甲的修士从阴影中走出,铠甲上流动着密文的纹路。
"crypto API,"修士自我介绍,声音清晰而有条理,"内核的加密框架。你看到的这些锁孔,每一个都是一种加密算法。"
林小源走近细看。左边一排是对称加密——AES、AES-256,一把钥匙同时用于加密和解密。中间是哈希——SHA256,单向计算,无法逆推。右边是认证加密——GCM,既加密又验证完整性。
"这么多算法,怎么选?"
crypto API 拍了拍铠甲上的纹路:"不用你选。你只需要调用统一的接口,告诉我你要做什么——加密、哈希、还是认证。我会根据你的硬件和需求,自动选择最优的实现。如果 CPU 支持 AES-NI 硬件加速,我就用硬件;没有的话,用软件实现。"
他伸手从墙上取下一个锁孔,注入一段密钥,锁孔便化作一个旋转的光轮,将林小源面前的一段明文吞入,吐出一串密文。
/*
* 内核 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");#include <stdio.h>
#include <string.h>
/*
* 内核 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");
}
int main() {
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");
return 0;
}二
密室深处,林小源看到一扇厚重的铁门,门上刻着 "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 是护盾——保护数据不被窃取。
内核加密之试
内核加密一章中,正文举出的对称加密算法代表是什么?