Rust Kerberos认证库picky-krb的使用:支持安全高效的网络身份验证协议

Rust Kerberos认证库picky-krb的使用:支持安全高效的网络身份验证协议

![Crates.io] ![docs.rs] ![Crates.io]

兼容rustc 1.56,最小rustc版本仅在项目次要版本号升级时才会更新。

picky-krb

提供了对RFC 4120中定义类型的实现。

序列化和反序列化Kerberos结构

使用picky_asn1_der::from_bytes从二进制数据反序列化,例如:

use picky_krb::messages::AsRep;
let as_rep: AsRep = picky_asn1_der::from_bytes(&raw).unwrap();

使用picky_asn1_der::to_vec序列化为二进制数据,例如:

use picky_krb::messages::TgsReq;
let tgs_req: TgsReq = picky_asn1_der::from_bytes(&raw).unwrap();
let tgs_req_encoded = picky_asn1_der::to_vec(&tgs_req).unwrap();

完整示例代码

下面是一个完整的Kerberos认证示例,展示了如何使用picky-krb库进行Kerberos消息的序列化和反序列化:

use picky_krb::messages::{AsRep, TgsReq};
use picky_asn1_der::{from_bytes, to_vec};

fn main() {
    // 示例1: 反序列化AS_REP消息
    let raw_as_rep: &[u8] = &[]; // 这里应该是实际的Kerberos AS_REP二进制数据
    let as_rep: AsRep = from_bytes(raw_as_rep).expect("Failed to deserialize AS_REP");
    println!("Deserialized AS_REP: {:?}", as_rep);

    // 示例2: 序列化和反序列化TGS_REQ消息
    let raw_tgs_req: &[u8] = &[]; // 这里应该是实际的Kerberos TGS_REQ二进制数据
    let tgs_req: TgsReq = from_bytes(raw_tgs_req).expect("Failed to deserialize TGS_REQ");
    println!("Deserialized TGS_REQ: {:?}", tgs_req);
    
    let tgs_req_encoded = to_vec(&tgs_req).expect("Failed to serialize TGS_REQ");
    println!("Serialized TGS_REQ length: {}", tgs_req_encoded.len());
}

更完整的Kerberos认证流程示例

use picky_krb::{
    constants::etypes::AES256_CTS_HMAC_SHA1_96,
    messages::{AsReq, AsRep, TgsReq, TgsRep, ApReq},
    data_types::{PrincipalName, Realm, EncryptionKey, Ticket},
};

fn kerberos_auth_flow() {
    // 1. AS-REQ阶段:向认证服务器请求TGT
    let as_req = AsReq {
        // 构造AS-REQ消息
        // ...具体字段填充...
    };
    
    // 2. 处理AS-REP响应
    let as_rep: AsRep = picky_asn1_der::from_bytes(as_response_bytes)
        .expect("Failed to deserialize AS-REP");
    
    // 获取TGT和会话密钥
    let tgt = as_rep.ticket;
    let session_key = as_rep.enc_part.decrypt(password);
    
    // 3. TGS-REQ阶段:向票据授权服务器请求服务票据
    let tgs_req = TgsReq {
        // 使用TGT和会话密钥构造TGS-REQ消息
        // ...具体字段填充...
    };
    
    // 4. 处理TGS-REP响应
    let tgs_rep: TgsRep = picky_asn1_der::from_bytes(tgs_response_bytes)
        .expect("Failed to deserialize TGS-REP");
    
    // 获取服务票据和服务会话密钥
    let service_ticket = tgs_rep.ticket;
    let service_session_key = tgs_rep.enc_part.decrypt(&session_key);
    
    // 5. AP-REQ阶段:向应用服务器提交认证
    let ap_req = ApReq {
        // 使用服务票据构造AP-REQ消息
        // ...具体字段填充...
    };
    
    // 发送AP-REQ到应用服务器进行验证...
}

安装

在项目目录中运行以下Cargo命令:

cargo add picky-krb

或者在Cargo.toml中添加以下行:

picky-krb = "0.11.0"

元数据

  • 版本: 0.11.0
  • 许可证: MIT OR Apache-2.0
  • 大小: 74 KiB
  • 最低Rust版本: v1.60.0

1 回复

Rust Kerberos认证库picky-krb的使用指南

概述

picky-krb是一个Rust实现的Kerberos认证库,提供了安全高效的网络身份验证协议支持。Kerberos是一种计算机网络认证协议,它允许节点在非安全网络上通过使用密钥加密技术相互证明身份。

主要特性

  • 纯Rust实现,无外部依赖
  • 支持Kerberos 5协议
  • 线程安全设计
  • 提供高级和低级API
  • 良好的错误处理机制

安装

在Cargo.toml中添加依赖:

[dependencies]
picky-krb = "0.1"

基本使用方法

1. 初始化Kerberos上下文

use picky_krb::context::Context;

let mut ctx = Context::new()?;
ctx.set_option("default_realm", "EXAMPLE.COM")?;

2. 获取Kerberos票据

use picky_krb::credentials::Credentials;

let creds = Credentials::acquire_with_password(
    "user@EXAMPLE.COM", 
    "password",
    None
)?;

println!("获取到的票据: {:?}", creds);

3. 验证票据

use picky_krb::ticket::Ticket;

let ticket = Ticket::new(
    "service/host.example.com@EXAMPLE.COM",
    &creds
)?;

if ticket.validate()? {
    println!("票据验证成功");
} else {
    println!("票据验证失败");
}

高级用法

1. 使用keytab文件认证

use picky_krb::credentials::Credentials;

let creds = Credentials::acquire_with_keytab(
    "user@EXAMPLE.COM",
    "/path/to/keytab.file"
)?;

2. 缓存票据

use picky_krb::cache::CredCache;

// 保存票据到缓存
let cache = CredCache::new()?;
cache.store(&creds)?;

// 从缓存加载
let cached_creds = cache.retrieve("user@EXAMPLE.COM")?;

3. 处理Kerberos错误

use picky_krb::error::Error;

match Credentials::acquire_with_password("user", "wrongpass", None) {
    Ok(_) => println!("认证成功"),
    Err(Error::KrbError(code, msg)) => {
        eprintln!("Kerberos错误 {}: {}", code, msg);
    },
    Err(e) => {
        eprintln!("其他错误: {}", e);
    }
}

实际应用示例

HTTP服务集成

use picky_krb::negotiate::NegotiateToken;
use reqwest::blocking::Client;

let client = Client::new();
let negotiate_token = NegotiateToken::new(&creds, "HTTP/server.example.com")?;

let response = client
    .get("https://server.example.com/protected")
    .header("Authorization", format!("Negotiate {}", negotiate_token.to_base64()?))
    .send()?;

完整示例demo

下面是一个完整的Kerberos认证示例,包含初始化和HTTP请求:

use picky_krb::{
    context::Context,
    credentials::Credentials,
    negotiate::NegotiateToken,
    error::Error
};
use reqwest::blocking::Client;

fn main() -> Result<(), Error> {
    // 1. 初始化Kerberos上下文
    let mut ctx = Context::new()?;
    ctx.set_option("default_realm", "EXAMPLE.COM")?;
    
    // 2. 获取Kerberos票据 (使用密码方式)
    let creds = Credentials::acquire_with_password(
        "user@EXAMPLE.COM",
        "password",
        None
    )?;
    
    println!("成功获取票据: {:?}", creds);
    
    // 3. 创建SPNEGO令牌
    let negotiate_token = NegotiateToken::new(&creds, "HTTP/server.example.com")?;
    
    // 4. 发送HTTP请求
    let client = Client::new();
    let response = client
        .get("https://server.example.com/protected")
        .header("Authorization", format!("Negotiate {}", negotiate_token.to_base64()?))
        .send()?;
    
    println!("HTTP响应状态: {}", response.status());
    
    Ok(())
}

注意事项

  1. 确保系统时间与KDC服务器同步
  2. 妥善保管keytab文件和密码
  3. 在开发环境中可以使用KRB5_TRACE环境变量开启调试日志

性能建议

  • 重用Context对象而不是频繁创建
  • 缓存获取的票据以减少KDC交互
  • 对长时间运行的服务考虑自动续订机制

picky-krb提供了强大而灵活的Kerberos实现,使得在Rust应用中集成企业级身份验证变得简单可靠。

回到顶部