keyctl – 密钥管理控制接口
1. 函数介绍
密钥保留服务是 Linux 内核的安全基础设施组件,用于安全地存储和管理密钥、密码、证书等敏感信息。
2. 函数原型
#include <sys/types.h>
#include <keyutils.h>
long keyctl(int cmd, ...);
3. 功能
执行各种密钥管理操作,包括:
- 创建和删除密钥
- 设置和获取密钥属性
- 链接和取消链接密钥
- 搜索和查找密钥
- 设置密钥权限
- 管理密钥环
4. 常用命令参数
// 密钥管理命令
#define KEYCTL_GET_KEYRING_ID 0 /* 获取密钥环 ID */
#define KEYCTL_JOIN_SESSION_KEYRING 1 /* 加入会话密钥环 */
#define KEYCTL_UPDATE 2 /* 更新密钥 */
#define KEYCTL_REVOKE 3 /* 撤销密钥 */
#define KEYCTL_CHOWN 4 /* 更改密钥所有者 */
#define KEYCTL_SETPERM 5 /* 设置密钥权限 */
#define KEYCTL_DESCRIBE 6 /* 描述密钥 */
#define KEYCTL_CLEAR 7 /* 清空密钥环 */
#define KEYCTL_LINK 8 /* 链接密钥 */
#define KEYCTL_UNLINK 9 /* 取消链接密钥 */
#define KEYCTL_SEARCH 10 /* 搜索密钥 */
#define KEYCTL_READ 11 /* 读取密钥 */
#define KEYCTL_INSTANTIATE 12 /* 实例化密钥 */
#define KEYCTL_NEGATE 13 /* 否定密钥 */
#define KEYCTL_SET_REQKEY_KEYRING 14 /* 设置请求密钥环 */
#define KEYCTL_SET_TIMEOUT 15 /* 设置密钥超时 */
#define KEYCTL_ASSUME_AUTHORITY 16 /* 假设权限 */
#define KEYCTL_GET_SECURITY 17 /* 获取安全上下文 */
#define KEYCTL_SESSION_TO_PARENT 18 /* 会话到父进程 */
#define KEYCTL_REJECT 19 /* 拒绝密钥 */
#define KEYCTL_INSTANTIATE_IOV 20 /* 实例化密钥 (iov) */
#define KEYCTL_INVALIDATE 21 /* 使密钥无效 */
#define KEYCTL_GET_PERSISTENT 22 /* 获取持久密钥环 */
5. 密钥类型
// 常见密钥类型
"user" // 用户定义的密钥
"logon" // 登录凭证密钥
"trusted" // 受信任的密钥
"encrypted" // 加密密钥
"dns_resolver" // DNS 解析器密钥
"rxrpc" // RxRPC 密钥
"syzkaller" // 系统调用模糊测试密钥
6. 返回值
- 成功时:返回值取决于具体命令
- 失败时:返回 -1,并设置
errno
7. 常见 errno 错误码
ENOKEY
: 密钥不存在EKEYEXPIRED
: 密钥已过期EKEYREVOKED
: 密钥已被撤销EACCES
: 权限不足EPERM
: 操作被拒绝EINVAL
: 参数无效ENOMEM
: 内存不足EDQUOT
: 配额超限EOPNOTSUPP
: 操作不支持
8. 相似函数,或关联函数
add_key()
: 添加新密钥request_key()
: 请求密钥keyctl()
系列函数/sbin/keyctl
: 用户态密钥管理工具/proc/keys
: 查看系统密钥信息/proc/key-users
: 查看密钥用户信息
9. 示例代码
示例1:基本使用 – 密钥创建和管理
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <keyutils.h>
#include <errno.h>
#include <string.h>
#ifndef SYS_keyctl
# define SYS_keyctl 250 // x86_64 架构下的系统调用号
#endif
// keyctl 系统调用包装函数
long keyctl_wrapper(int cmd, ...) {
va_list args;
va_start(args, cmd);
long result = syscall(SYS_keyctl, cmd, va_arg(args, long),
va_arg(args, long), va_arg(args, long),
va_arg(args, long));
va_end(args);
return result;
}
int main() {
printf("=== keyctl 基本使用演示 ===\n");
// 检查密钥支持
key_serial_t session_keyring = keyctl(KEYCTL_GET_KEYRING_ID,
KEY_SPEC_SESSION_KEYRING, 0);
if (session_keyring == -1) {
printf("错误: 系统不支持密钥保留服务: %s\n", strerror(errno));
return 1;
}
printf("✓ 密钥保留服务可用\n");
printf("会话密钥环 ID: %d\n", session_keyring);
// 创建一个用户密钥
const char *key_desc = "my_test_key";
const char *key_data = "This is my secret data";
key_serial_t key = add_key("user", key_desc, key_data, strlen(key_data),
KEY_SPEC_SESSION_KEYRING);
if (key == -1) {
printf("创建密钥失败: %s\n", strerror(errno));
return 1;
}
printf("✓ 成功创建密钥,ID: %d\n", key);
// 描述密钥
char description[256];
long desc_len = keyctl(KEYCTL_DESCRIBE, key, (long)description,
sizeof(description), 0);
if (desc_len != -1) {
description[desc_len] = '\0';
printf("密钥描述: %s\n", description);
}
// 读取密钥数据
char read_data[256];
long data_len = keyctl(KEYCTL_READ, key, (long)read_data,
sizeof(read_data), 0);
if (data_len != -1) {
read_data[data_len] = '\0';
printf("密钥数据: %s\n", read_data);
}
// 设置密钥超时(30秒后过期)
if (keyctl(KEYCTL_SET_TIMEOUT, key, 30, 0, 0) == 0) {
printf("✓ 设置密钥超时为 30 秒\n");
}
// 获取密钥安全上下文
char security_context[256];
long sec_len = keyctl(KEYCTL_GET_SECURITY, key,
(long)security_context, sizeof(security_context), 0);
if (sec_len != -1) {
security_context[sec_len] = '\0';
printf("安全上下文: %s\n", security_context);
}
// 撤销密钥
if (keyctl(KEYCTL_REVOKE, key, 0, 0, 0) == 0) {
printf("✓ 成功撤销密钥\n");
}
return 0;
}
示例2:密钥环操作
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <keyutils.h>
#include <errno.h>
#include <string.h>
void demonstrate_keyring_operations() {
printf("=== 密钥环操作演示 ===\n");
// 获取各种密钥环 ID
key_serial_t session_ring = keyctl(KEYCTL_GET_KEYRING_ID,
KEY_SPEC_SESSION_KEYRING, 0);
key_serial_t process_ring = keyctl(KEYCTL_GET_KEYRING_ID,
KEY_SPEC_PROCESS_KEYRING, 0);
key_serial_t thread_ring = keyctl(KEYCTL_GET_KEYRING_ID,
KEY_SPEC_THREAD_KEYRING, 0);
printf("密钥环 ID:\n");
printf(" 会话密钥环: %d\n", session_ring);
printf(" 进程密钥环: %d\n", process_ring);
printf(" 线程密钥环: %d\n", thread_ring);
// 创建自定义密钥环
key_serial_t custom_ring = add_key("keyring", "my_custom_ring",
NULL, 0, KEY_SPEC_SESSION_KEYRING);
if (custom_ring != -1) {
printf("✓ 创建自定义密钥环: %d\n", custom_ring);
// 在自定义密钥环中创建密钥
key_serial_t ring_key = add_key("user", "ring_key",
"data in ring", 12, custom_ring);
if (ring_key != -1) {
printf("✓ 在自定义密钥环中创建密钥: %d\n", ring_key);
}
// 清空自定义密钥环
if (keyctl(KEYCTL_CLEAR, custom_ring, 0, 0, 0) == 0) {
printf("✓ 清空自定义密钥环\n");
}
// 撤销自定义密钥环
if (keyctl(KEYCTL_REVOKE, custom_ring, 0, 0, 0) == 0) {
printf("✓ 撤销自定义密钥环\n");
}
}
// 加入新的会话密钥环
key_serial_t new_session = keyctl(KEYCTL_JOIN_SESSION_KEYRING,
(long)"new_session", 0, 0, 0);
if (new_session != -1) {
printf("✓ 加入新的会话密钥环: %d\n", new_session);
}
}
void demonstrate_key_search() {
printf("\n=== 密钥搜索演示 ===\n");
// 创建测试密钥
key_serial_t test_key = add_key("user", "search_test",
"search data", 11,
KEY_SPEC_SESSION_KEYRING);
if (test_key == -1) {
printf("创建测试密钥失败: %s\n", strerror(errno));
return;
}
printf("创建测试密钥: %d\n", test_key);
// 搜索密钥
key_serial_t found_key = keyctl(KEYCTL_SEARCH,
KEY_SPEC_SESSION_KEYRING,
(long)"user", (long)"search_test", 0);
if (found_key != -1) {
printf("✓ 找到密钥: %d\n", found_key);
// 验证找到的密钥
if (found_key == test_key) {
printf("✓ 验证成功:找到的密钥 ID 匹配\n");
}
} else {
printf("搜索密钥失败: %s\n", strerror(errno));
}
// 撤销测试密钥
keyctl(KEYCTL_REVOKE, test_key, 0, 0, 0);
}
void demonstrate_key_permissions() {
printf("\n=== 密钥权限演示 ===\n");
// 创建测试密钥
key_serial_t perm_key = add_key("user", "perm_test",
"permission data", 15,
KEY_SPEC_SESSION_KEYRING);
if (perm_key == -1) {
printf("创建权限测试密钥失败: %s\n", strerror(errno));
return;
}
printf("创建权限测试密钥: %d\n", perm_key);
// 设置密钥权限
// 权限格式: possessor|user|group|other
// 每个字段: view|read|write|search|link|setattr|all
key_perm_t permissions = KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ;
if (keyctl(KEYCTL_SETPERM, perm_key, permissions, 0, 0) == 0) {
printf("✓ 设置密钥权限成功\n");
// 描述密钥查看权限
char desc[256];
long desc_len = keyctl(KEYCTL_DESCRIBE, perm_key,
(long)desc, sizeof(desc), 0);
if (desc_len != -1) {
desc[desc_len] = '\0';
printf("更新后的密钥描述: %s", desc);
}
} else {
printf("设置密钥权限失败: %s\n", strerror(errno));
}
// 更改密钥所有者(需要特权)
if (keyctl(KEYCTL_CHOWN, perm_key, getuid(), 0, 0) == 0) {
printf("✓ 更改密钥所有者成功\n");
} else {
if (errno == EPERM) {
printf("ℹ 更改所有者需要特权权限\n");
} else {
printf("更改所有者失败: %s\n", strerror(errno));
}
}
// 撤销密钥
keyctl(KEYCTL_REVOKE, perm_key, 0, 0, 0);
}
int main() {
printf("=== keyctl 密钥环操作演示 ===\n");
// 检查密钥支持
if (keyctl(KEYCTL_GET_KEYRING_ID, KEY_SPEC_SESSION_KEYRING, 0) == -1) {
printf("错误: 系统不支持密钥保留服务\n");
return 1;
}
demonstrate_keyring_operations();
demonstrate_key_search();
demonstrate_key_permissions();
return 0;
}
示例3:密钥安全和加密操作
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <keyutils.h>
#include <errno.h>
#include <string.h>
#include <time.h>
void demonstrate_encrypted_keys() {
printf("=== 加密密钥演示 ===\n");
// 检查是否支持加密密钥
printf("系统支持的密钥类型:\n");
system("cat /proc/key-types 2>/dev/null | grep -E 'user|encrypted|trusted' || "
"echo '无法读取密钥类型信息'");
// 创建用户密钥(基础加密)
const char *encrypted_data = "sensitive_encrypted_data";
key_serial_t enc_key = add_key("user", "encrypted_secret",
encrypted_data, strlen(encrypted_data),
KEY_SPEC_SESSION_KEYRING);
if (enc_key != -1) {
printf("✓ 创建加密数据密钥: %d\n", enc_key);
// 设置超时以增强安全性
if (keyctl(KEYCTL_SET_TIMEOUT, enc_key, 300, 0, 0) == 0) { // 5分钟
printf("✓ 设置密钥超时为 5 分钟\n");
}
// 读取密钥数据
char buffer[256];
long read_len = keyctl(KEYCTL_READ, enc_key, (long)buffer,
sizeof(buffer), 0);
if (read_len != -1) {
buffer[read_len] = '\0';
printf("读取加密数据长度: %ld 字节\n", read_len);
}
} else {
printf("创建加密密钥失败: %s\n", strerror(errno));
}
}
void demonstrate_key_lifecycle() {
printf("\n=== 密钥生命周期管理 ===\n");
// 创建密钥
const char *key_data = "lifecycle_test_data";
key_serial_t key = add_key("user", "lifecycle_test",
key_data, strlen(key_data),
KEY_SPEC_SESSION_KEYRING);
if (key == -1) {
printf("创建密钥失败: %s\n", strerror(errno));
return;
}
printf("1. 创建密钥: %d\n", key);
// 描述密钥状态
char desc[256];
long desc_len = keyctl(KEYCTL_DESCRIBE, key, (long)desc, sizeof(desc), 0);
if (desc_len != -1) {
desc[desc_len] = '\0';
printf("2. 密钥状态: %s", desc);
}
// 更新密钥数据
const char *new_data = "updated_lifecycle_data";
if (keyctl(KEYCTL_UPDATE, key, (long)new_data, strlen(new_data), 0) == 0) {
printf("3. ✓ 更新密钥数据成功\n");
}
// 设置短期超时
if (keyctl(KEYCTL_SET_TIMEOUT, key, 10, 0, 0) == 0) { // 10秒
printf("4. ✓ 设置 10 秒超时\n");
}
// 等待几秒观察超时效果
printf("5. 等待 12 秒观察超时效果...\n");
sleep(12);
// 尝试访问已过期的密钥
char buffer[256];
long read_len = keyctl(KEYCTL_READ, key, (long)buffer, sizeof(buffer), 0);
if (read_len == -1) {
if (errno == EKEYEXPIRED) {
printf("6. ✓ 密钥已正确过期\n");
} else {
printf("6. 访问密钥失败: %s\n", strerror(errno));
}
}
// 撤销密钥(即使已过期)
if (keyctl(KEYCTL_REVOKE, key, 0, 0, 0) == 0) {
printf("7. ✓ 撤销密钥成功\n");
}
}
void demonstrate_key_security_analysis() {
printf("\n=== 密钥安全分析 ===\n");
// 显示当前用户的密钥使用情况
printf("当前密钥使用情况:\n");
system("cat /proc/key-users 2>/dev/null | head -10 || echo '无法读取密钥用户信息'");
// 显示系统密钥信息
printf("\n系统密钥信息:\n");
system("cat /proc/keys 2>/dev/null | head -10 || echo '无法读取密钥信息'");
// 显示密钥配额信息
printf("\n密钥配额信息:\n");
system("cat /proc/sys/kernel/keys/* 2>/dev/null || echo '无法读取密钥配额'");
// 安全建议
printf("\n密钥安全最佳实践:\n");
printf(" • 使用适当的超时设置\n");
printf(" • 设置最小必要权限\n");
printf(" • 定期清理过期密钥\n");
printf(" • 避免在日志中记录密钥数据\n");
printf(" • 使用加密存储敏感数据\n");
printf(" • 监控密钥使用情况\n");
}
int main() {
printf("=== keyctl 安全和加密操作演示 ===\n");
// 检查密钥支持
if (keyctl(KEYCTL_GET_KEYRING_ID, KEY_SPEC_SESSION_KEYRING, 0) == -1) {
printf("错误: 系统不支持密钥保留服务\n");
return 1;
}
printf("✓ 密钥保留服务可用\n");
demonstrate_encrypted_keys();
demonstrate_key_lifecycle();
demonstrate_key_security_analysis();
return 0;
}
示例4:密钥管理工具和监控
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <keyutils.h>
#include <errno.h>
#include <string.h>
#include <time.h>
void show_key_statistics() {
printf("=== 密钥统计信息 ===\n");
// 显示密钥数量
printf("系统密钥统计:\n");
system("wc -l /proc/keys 2>/dev/null | awk '{print \"总密钥数: \" $1-1}' || "
"echo '无法统计密钥数量'");
// 显示密钥用户信息
printf("\n密钥用户统计:\n");
system("cat /proc/key-users 2>/dev/null | head -5 || echo '无法读取用户统计'");
// 显示密钥类型分布
printf("\n密钥类型分布:\n");
system("awk '{print $4}' /proc/keys 2>/dev/null | sort | uniq -c | head -10 || "
"echo '无法分析密钥类型'");
}
void interactive_key_manager() {
int choice;
char input[256];
while (1) {
printf("\n=== 密钥管理菜单 ===\n");
printf("1. 列出当前密钥\n");
printf("2. 创建新密钥\n");
printf("3. 查找密钥\n");
printf("4. 删除密钥\n");
printf("5. 显示密钥统计\n");
printf("6. 清空会话密钥环\n");
printf("0. 退出\n");
printf("请选择操作: ");
if (scanf("%d", &choice) != 1) {
printf("输入无效,请重新选择\n");
while (getchar() != '\n'); // 清空输入缓冲区
continue;
}
switch (choice) {
case 1:
printf("当前会话密钥:\n");
system("keyctl list @s 2>/dev/null || echo '无法列出密钥'");
break;
case 2: {
printf("输入密钥描述: ");
scanf("%255s", input);
printf("输入密钥数据: ");
scanf("%255s", input + 128); // 简化处理
key_serial_t new_key = add_key("user", input,
input + 128,
strlen(input + 128),
KEY_SPEC_SESSION_KEYRING);
if (new_key != -1) {
printf("✓ 成功创建密钥: %d\n", new_key);
} else {
printf("❌ 创建密钥失败: %s\n", strerror(errno));
}
break;
}
case 3: {
printf("输入要查找的密钥描述: ");
scanf("%255s", input);
key_serial_t found_key = keyctl(KEYCTL_SEARCH,
KEY_SPEC_SESSION_KEYRING,
(long)"user", (long)input, 0);
if (found_key != -1) {
printf("✓ 找到密钥: %d\n", found_key);
} else {
printf("❌ 未找到密钥: %s\n", strerror(errno));
}
break;
}
case 4: {
printf("输入要删除的密钥 ID: ");
int key_id;
if (scanf("%d", &key_id) == 1) {
if (keyctl(KEYCTL_REVOKE, key_id, 0, 0, 0) == 0) {
printf("✓ 成功撤销密钥: %d\n", key_id);
} else {
printf("❌ 撤销密钥失败: %s\n", strerror(errno));
}
} else {
printf("输入无效\n");
}
break;
}
case 5:
show_key_statistics();
break;
case 6:
if (keyctl(KEYCTL_CLEAR, KEY_SPEC_SESSION_KEYRING, 0, 0, 0) == 0) {
printf("✓ 成功清空会话密钥环\n");
} else {
printf("❌ 清空密钥环失败: %s\n", strerror(errno));
}
break;
case 0:
printf("退出密钥管理工具\n");
return;
default:
printf("无效选择,请重新输入\n");
break;
}
}
}
void demonstrate_advanced_key_operations() {
printf("\n=== 高级密钥操作 ===\n");
// 创建密钥环
key_serial_t keyring = add_key("keyring", "advanced_test_ring",
NULL, 0, KEY_SPEC_SESSION_KEYRING);
if (keyring != -1) {
printf("✓ 创建测试密钥环: %d\n", keyring);
// 在密钥环中创建多个密钥
for (int i = 1; i <= 3; i++) {
char desc[32], data[32];
snprintf(desc, sizeof(desc), "key_%d", i);
snprintf(data, sizeof(data), "data_%d", i);
key_serial_t key = add_key("user", desc, data, strlen(data), keyring);
if (key != -1) {
printf(" ✓ 创建密钥 %s: %d\n", desc, key);
}
}
// 列出密钥环内容
printf("密钥环内容:\n");
char buffer[1024];
long len = keyctl(KEYCTL_READ, keyring, (long)buffer, sizeof(buffer), 0);
if (len != -1) {
// 简化显示
printf(" 密钥环包含 %ld 字节数据\n", len);
}
// 清空密钥环
if (keyctl(KEYCTL_CLEAR, keyring, 0, 0, 0) == 0) {
printf("✓ 清空密钥环成功\n");
}
// 撤销密钥环
keyctl(KEYCTL_REVOKE, keyring, 0, 0, 0);
}
}
void key_monitoring_demo() {
printf("\n=== 密钥监控演示 ===\n");
printf("实时密钥监控 (按 Ctrl+C 停止):\n");
// 显示初始状态
printf("初始密钥数量: ");
system("wc -l /proc/keys 2>/dev/null | awk '{print $1-1}' || echo 'unknown'");
// 创建测试密钥并监控变化
key_serial_t test_key = add_key("user", "monitor_test",
"monitor data", 12,
KEY_SPEC_SESSION_KEYRING);
if (test_key != -1) {
printf("创建测试密钥后数量: ");
system("wc -l /proc/keys 2>/dev/null | awk '{print $1-1}' || echo 'unknown'");
// 撤销密钥
keyctl(KEYCTL_REVOKE, test_key, 0, 0, 0);
printf("撤销测试密钥后数量: ");
system("wc -l /proc/keys 2>/dev/null | awk '{print $1-1}' || echo 'unknown'");
}
}
int main() {
printf("=== keyctl 高级管理和监控工具 ===\n");
// 检查密钥支持
if (keyctl(KEYCTL_GET_KEYRING_ID, KEY_SPEC_SESSION_KEYRING, 0) == -1) {
printf("错误: 系统不支持密钥保留服务\n");
return 1;
}
printf("✓ 密钥保留服务可用\n");
// 显示系统信息
printf("\n系统密钥信息:\n");
system("uname -a");
// 执行高级操作演示
demonstrate_advanced_key_operations();
// 显示统计信息
show_key_statistics();
// 监控演示
key_monitoring_demo();
// 启动交互式管理器(如果需要)
char choice;
printf("\n是否启动交互式密钥管理器? (y/N): ");
if (scanf(" %c", &choice) == 1 && (choice == 'y' || choice == 'Y')) {
interactive_key_manager();
}
return 0;
}
10. 密钥权限说明
// 密钥权限位定义
#define KEY_POS_VIEW 0x01000000 /* 持有者可查看 */
#define KEY_POS_READ 0x02000000 /* 持有者可读取 */
#define KEY_POS_WRITE 0x04000000 /* 持有者可写入 */
#define KEY_POS_SEARCH 0x08000000 /* 持有者可搜索 */
#define KEY_POS_LINK 0x10000000 /* 持有者可链接 */
#define KEY_POS_SETATTR 0x20000000 /* 持有者可设置属性 */
#define KEY_POS_ALL 0x3f000000 /* 持有者所有权限 */
#define KEY_USR_VIEW 0x00010000 /* 用户可查看 */
#define KEY_USR_READ 0x00020000 /* 用户可读取 */
#define KEY_USR_WRITE 0x00040000 /* 用户可写入 */
#define KEY_USR_SEARCH 0x00080000 /* 用户可搜索 */
#define KEY_USR_LINK 0x00100000 /* 用户可链接 */
#define KEY_USR_SETATTR 0x00200000 /* 用户可设置属性 */
#define KEY_USR_ALL 0x003f0000 /* 用户所有权限 */
#define KEY_GRP_VIEW 0x00000100 /* 组可查看 */
#define KEY_GRP_READ 0x00000200 /* 组可读取 */
#define KEY_GRP_WRITE 0x00000400 /* 组可写入 */
#define KEY_GRP_SEARCH 0x00000800 /* 组可搜索 */
#define KEY_GRP_LINK 0x00001000 /* 组可链接 */
#define KEY_GRP_SETATTR 0x00002000 /* 组可设置属性 */
#define KEY_GRP_ALL 0x00003f00 /* 组所有权限 */
#define KEY_OTH_VIEW 0x00000001 /* 其他可查看 */
#define KEY_OTH_READ 0x00000002 /* 其他可读取 */
#define KEY_OTH_WRITE 0x00000004 /* 其他可写入 */
#define KEY_OTH_SEARCH 0x00000008 /* 其他可搜索 */
#define KEY_OTH_LINK 0x00000010 /* 其他可链接 */
#define KEY_OTH_SETATTR 0x00000020 /* 其他可设置属性 */
#define KEY_OTH_ALL 0x0000003f /* 其他所有权限 */
11. 实际应用场景
场景1:网络认证
void network_authentication_keys() {
// 存储网络认证凭证
add_key("user", "wifi_password", "secret123", 9,
KEY_SPEC_SESSION_KEYRING);
}
场景2:文件系统加密
void filesystem_encryption_keys() {
// 存储加密文件系统密钥
add_key("encrypted", "fs_encryption_key", key_data, key_len,
KEY_SPEC_SESSION_KEYRING);
}
场景3:安全通信
void secure_communication_keys() {
// 存储 TLS/SSL 会话密钥
add_key("user", "tls_session_key", session_key, key_len,
KEY_SPEC_PROCESS_KEYRING);
}
12. 注意事项
使用 keyctl
时需要注意:
- 权限要求: 某些操作需要特殊权限
- 内存安全: 密钥数据在内存中的安全处理
- 生命周期: 正确管理密钥的创建、使用和销毁
- 超时设置: 合理设置密钥超时以增强安全性
- 权限控制: 设置最小必要权限
- 系统资源: 监控密钥使用对系统资源的影响
13. 系统配置检查
# 检查密钥支持
grep CONFIG_KEYS /boot/config-$(uname -r)
# 查看密钥信息
cat /proc/keys
cat /proc/key-users
# 检查密钥配额
cat /proc/sys/kernel/keys/maxkeys
cat /proc/sys/kernel/keys/maxbytes
# 使用 keyctl 工具
keyctl list @s
keyctl show
总结
主要应用:
1. 网络认证和安全通信
2. 文件系统加密
3. 应用程序密钥管理
4. 系统安全服务
5. 容器和虚拟化安全
使用要点:
1. 需要理解密钥权限模型
2. 注意密钥生命周期管理
3. 合理设置超时和权限
4. 监控密钥使用情况
5. 配合用户态工具使用效果更佳