You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用keytab解密Kerberos票据获取用户名及相关参数说明

Kerberos keytab解密Ticket提取用户名实现指南

核心概念说明

  • ccache全称为Credentials Cache(凭证缓存),是MIT Kerberos库用来存储客户端侧已获取Kerberos凭证的本地存储结构。你当前仅需实现服务端票据解密、提取用户名的场景完全不需要用到ccache,你之前查阅的两份官方示例属于客户端工具/协议扩展测试场景,需要读取客户端自身持有的凭证,才会涉及ccache相关逻辑,和你当前的服务端验票场景无关,这部分代码可以直接忽略。

核心函数参数说明

你提到的krb5_server_decrypt_ticket_keytab()是MIT Kerberos官方提供的服务端票据解密入口,各参数含义如下:

  • krb5_context context:Kerberos上下文句柄,所有Kerberos API调用都需要先初始化该上下文,通过krb5_init_context()即可获取
  • krb5_keytab keytab:已加载的keytab文件句柄,通过krb5_kt_resolve()传入keytab文件路径加载得到
  • krb5_ticket *ticket:待解密的票据结构体,你持有的base64编码票据需要先做base64解码得到二进制流,再通过krb5_decode_ticket()解析为该结构体
  • 返回值:返回0代表解密校验成功,非0为对应错误码,可通过krb5_get_error_message()获取可读的错误描述

该函数在解密的同时会自动完成票据全链路合法性校验,包括时间有效期、签名有效性、内容是否篡改,返回0即代表票据合法,无需额外增加校验逻辑。

完整实现流程

你仅需持有的base64编码票据、keytab文件两个输入即可完成全流程,步骤如下:

  1. 初始化Kerberos上下文,调用krb5_init_context()获取上下文句柄
  2. 加载keytab文件,调用krb5_kt_resolve()传入keytab绝对路径拿到keytab句柄
  3. 对base64编码的票据做解码,得到二进制格式的票据原始字节流
  4. 调用krb5_decode_ticket()将二进制字节流解析为krb5_ticket类型的结构体指针对象
  5. 调用krb5_server_decrypt_ticket_keytab()传入上下文、keytab句柄、票据指针完成解密校验
  6. 校验通过后,用户名存储在ticket->enc_part2->client->data字段,对应的用户所属域存储在ticket->enc_part2->client->realm.data字段
  7. 按顺序释放票据、keytab、上下文等资源,避免内存泄漏

最小可运行代码示例

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <krb5.h>
#include <openssl/bio.h>
#include <openssl/evp.h>

// 简易base64解码实现,可替换为任意base64解码库
int base64_decode(const char *b64input, unsigned char **out, int *out_len) {
    BIO *b64 = BIO_new(BIO_f_base64());
    BIO *bmem = BIO_new_mem_buf(b64input, strlen(b64input));
    b64 = BIO_push(b64, bmem);
    BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
    *out_len = BIO_read(b64, *out, strlen(b64input));
    BIO_free_all(b64);
    return 0;
}

int main(int argc, char **argv) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s <keytab_abs_path> <base64_encoded_ticket>\n", argv[0]);
        return 1;
    }
    const char *keytab_path = argv[1];
    const char *b64_ticket = argv[2];

    krb5_context ctx = NULL;
    krb5_keytab kt = NULL;
    krb5_ticket *ticket = NULL;
    krb5_error_code ret;
    unsigned char *ticket_bin = NULL;
    int ticket_bin_len = 0;

    // 初始化Kerberos上下文
    ret = krb5_init_context(&ctx);
    if (ret) {
        fprintf(stderr, "Init krb context failed, code: %d\n", ret);
        goto cleanup;
    }

    // 加载keytab文件
    ret = krb5_kt_resolve(ctx, keytab_path, &kt);
    if (ret) {
        fprintf(stderr, "Load keytab failed: %s\n", krb5_get_error_message(ctx, ret));
        goto cleanup;
    }

    // 解码base64票据
    ticket_bin = malloc(strlen(b64_ticket));
    memset(ticket_bin, 0, strlen(b64_ticket));
    base64_decode(b64_ticket, &ticket_bin, &ticket_bin_len);

    // 解析二进制票据为结构体
    krb5_data ticket_data = make_data(ticket_bin, ticket_bin_len);
    ret = krb5_decode_ticket(&ticket_data, &ticket);
    if (ret) {
        fprintf(stderr, "Parse ticket failed: %s\n", krb5_get_error_message(ctx, ret));
        goto cleanup;
    }

    // 用keytab解密并校验票据
    ret = krb5_server_decrypt_ticket_keytab(ctx, kt, ticket);
    if (ret) {
        fprintf(stderr, "Decrypt ticket failed: %s\n", krb5_get_error_message(ctx, ret));
        goto cleanup;
    }

    // 提取用户名和域信息
    char *username = ticket->enc_part2->client->data;
    char *realm = ticket->enc_part2->client->realm.data;
    printf("Ticket valid. Username: %s@%s\n", username, realm);

cleanup:
    if (ticket_bin) free(ticket_bin);
    if (ticket) krb5_free_ticket(ctx, ticket);
    if (kt) krb5_kt_close(ctx, kt);
    if (ctx) krb5_free_context(ctx);
    return ret;
}

编译时链接Kerberos和OpenSSL库即可,编译命令:
gcc -o ticket_decrypt ticket_decrypt.c -lkrb5 -lcrypto

官方示例说明

你之前找到的两份官方示例均不适用于当前场景:

  • kvno.c是客户端侧的密钥版本号查询工具,涉及ccache的逻辑是为了读取客户端自身的TGT凭证,用于向KDC请求服务端密钥版本,和服务端验票场景无关
  • s4u2proxy.c是Kerberos S4U2代理扩展的测试代码,涉及ccache的逻辑是为了存储代理服务自身的凭证,用于实现代用户请求其他服务票据的逻辑,同样不属于纯服务端验票场景
    两份示例的运行依赖完整的Kerberos客户端环境、KDC连通性,不需要为了当前需求调试运行这两份代码,直接使用上述最小实现即可。

内容的提问来源于stack exchange,提问作者Rachel91

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 23:06:22