我正在使用 spnego ( http://spnego.sourceforge.net ) 用于 JBoss 下的 kerberos 身份验证。

我需要解密 kerberos 票证才能访问包含 PAC 数据的授权数据。需要 PAC 数据来决定向用户授予哪些角色。

如何访问和解密kerberos票证?我已经在网上搜索了示例,但没有费力。

有帮助吗?

解决方案

这些家伙有完整的PAC解码实施:

http://jaaslounge.sourceforge.net/

您可以这样使用令牌解析器:

HttpServletRequest request = (HttpServletRequest) req;
String header = request.getHeader("Authorization");
byte[] base64Token = header.substring(10).getBytes("UTF-8");
byte[] spnegoHeader = Base64.decode(base64Token);

SpnegoInitToken spnegoToken = new SpnegoInitToken(spnegoHeader);

如果您想解密基础的Kerberos票,您将需要跳一些篮球。不确定您是否需要。

授予

其他提示

我已经成功地使用了Servlet过滤器 http://spnego.sourceforge.net 与PAC解析器的结合 http://jaaslounge.sourceforge.net/ 无需使用der/asn.1解析器明确地做某事:

/** 
 * Retrieve LogonInfo (for example, Group SID) from the PAC Authorization Data
 * from a Kerberos Ticket that was issued by Active Directory.
 */  
byte[] kerberosTokenData = gssapiData;
try {
    SpnegoToken token = SpnegoToken.parse(gssapiData);
    kerberosTokenData = token.getMechanismToken();
} catch (DecodingException dex) {
    // Chromium bug: sends a Kerberos response instead of an spnego response 
    // with a Kerberos mechanism
} catch (Exception ex) {
    log.error("", ex);
}   

try {
    Object[] keyObjs = IteratorUtils.toArray(loginContext.getSubject()
                         .getPrivateCredentials(KerberosKey.class).iterator());
    KerberosKey[] keys = new KerberosKey[keyObjs.length];
    System.arraycopy(keyObjs, 0, keys, 0, keyObjs.length);

    KerberosToken token = new KerberosToken(kerberosTokenData, keys);
    log.info("Authorizations: "); 
    for (KerberosAuthData authData : token.getTicket().getEncData()
                                             .getUserAuthorizations()) {
        if (authData instanceof KerberosPacAuthData) {
            PacSid[] groupSIDs = ((KerberosPacAuthData) authData)
                                      .getPac().getLogonInfo().getGroupSids();
            log.info("GroupSids: " + Arrays.toString(groupSIDs));
            response.getWriter().println("Found group SIDs: " + 
                Arrays.toString(groupSIDs));
        } else {
            log.info("AuthData without PAC: " + authData.toString());
        }   
    }   
} catch (Exception ex) {
    log.error("", ex);
}   

我还写了一个新的httpfilter(摘自spnego.sf.net):spnego-pac,它通过getuserprincipal()披露了logoninfo。

可以在此处找到一个完整说明上述代码的示例项目:

https://github.com/eleotlecram/jetty-spnego-demo

Spnego-PAC过滤器(在上面的示例中使用)可以在此处找到:

https://github.com/eleotlecram/spnego.sf.net-fork

希望这对任何人都有帮助。

__
马塞尔

如果您从 spnegoToken 像这样:

byte[] mechanismToken = spnegoToken.getMechanismToken(); 

令牌令牌通常是 KerberosApRequest. 。有一个 KerberosToken 构造函数 KerberosApRequest. 。只需传递 mechanismToken 字节数组以及解密内容的钥匙。

我针对这个问题提供了我自己的解决方案:

我的解决方案基于 BouncyCastle 库(用于解析令牌的部分)和 JaasLounge(用于解密令牌的加密部分)。不幸的是,从 JaasLounge 解码整个 spnego 令牌的代码未能满足我的要求。我必须自己写。

我已经逐部分解码了票证,首先从 byte[] 数组构造 DERObjects:

private DERObject[] readDERObjects(byte[] bytes) throws IOException {
    ASN1InputStream stream = new ASN1InputStream(new ByteArrayInputStream(
        bytes));
    List<DERObject> objects = new ArrayList<DERObject>();
    DERObject curObj;
    while ((curObj = stream.readObject()) != null) {
        objects.add(untag(curObj));
    }
    return objects.toArray(new DERObject[0]);
}

untag() 是我的辅助函数,用于删除 DERTaggedObject 包装

private DERObject untag(DERObject src) {
    if (src instanceof DERTaggedObject) {
        return ((DERTaggedObject) src).getObject();
    }
    return src;
}

为了从给定的 DERObject 中提取 DERObject 序列,我编写了另一个辅助函数:

private DERObject[] readDERObjects(DERObject container) throws IOException {
// do operation varying from the type of container
if (container instanceof DERSequence) {
    // decode using enumerator
    List<DERObject> objects = new ArrayList<DERObject>();
    DERSequence seq = (DERSequence) container;
    Enumeration enumer = seq.getObjects();
    while (enumer.hasMoreElements()) {
    DERObject curObj = (DERObject) enumer.nextElement();
    objects.add(untag(curObj));
    }
    return objects.toArray(new DERObject[0]);
}
if (container instanceof DERApplicationSpecific) {
    DERApplicationSpecific aps = (DERApplicationSpecific) container;
    byte[] bytes = aps.getContents();
    return readDERObjects(bytes);
}
if (container instanceof DEROctetString) {
    DEROctetString octets = (DEROctetString) container;
    byte[] bytes = octets.getOctets();
    return readDERObjects(bytes);
}
throw new IllegalArgumentException("Unable to decode sequence from "+container);
}

最后,当我得到包含加密部分的 DEROctetStream 时,我刚刚使用了 KerberosEncData:

KerberosEncData encData = new KerberosEncData(decrypted, matchingKey);

我们从客户端浏览器中收到的字节序列将被解析为单个derapplicationspefific,ticket root -0。
根包含:

  • DERObjectIdentifier - SPNEGO OID
  • DERSequence - 1 级

1 级包含:

  • DERObjectIdentifier 的序列 - 机械类型
  • DEROctetString - 包装的 DERApplicationSepecific - 级别 2

2 级包含:

  • DERObjectIndentifier - Kerberos OID
  • KRB5_AP_REQ 标签 0x01 0x00, ,解析为布尔值(假)
  • DERApplicationSpecific - DERSequence 容器 - 级别 3

第 3 级包含:

  • 版本号 - 应为 5
  • 消息类型 -​​ 14 (AP_REQ)
  • AP 选项 (DERBITString)
  • DERApplicationSpecific - 使用票证部分包装 DERSequence
  • 具有附加票证部分的 DERSeqeuence - 未处理

票证部分 - 第 4 级包含:

  • 门票版本 - 应该是 5
  • 票证领域 - 用户进行身份验证的领域的名称
  • DER 服务器名称的序列。每个服务器名称都是由 2 个字符串组成的 DERSequence:服务器名称和实例名称
  • 具有加密部分的 DERSequence

加密部分序列(级别 5)包含:

  • 使用的算法数量
    • 1, 3 - DES
    • 16 - des3-cbc-sha1-kd
    • 17 - ETYPE-AES128-CTS-HMAC-SHA1-96
    • 18 - ETYPE-AES256-CTS-HMAC-SHA1-96
    • 23 - RC4-HMAC
    • 24 - RC4-HMAC-EXP
  • 密钥版本号
  • 加密部分(DEROctetStream)

问题出在 DERBoolean 构造函数上,当找到序列 0x01 0x00 时,它会抛出 ArrayIndexOutOfBoundException。我必须更改该构造函数:

public DERBoolean(
    byte[]       value)
{
// 2011-01-24 llech make it byte[0] proof, sequence 01 00 is KRB5_AP_REQ
if (value.length == 0)
    this.value = 0;
else
    this.value = value[0];
}

哇已经有一段时间了,因为我使用了Spnego(将近一年)...您问一个非常酷的问题。

我做了一些挖掘,并打算尝试使用MS-AD工作的一些代码,但今天没有感觉到: - /

无论如何,我通过Google找到了此链接:http://www.google.com/url?sa=t&source=web&cd=1&sqi=2&ved=0CBMQFjAA&url=http%3A%2F%2Fbofriis.dk%2Ffiles%2Fms_kerberos_pac.pdf&rct=j&q=java%20kerberos%20privilege%20attribute% 20certificate&ei = 2fastBalgcp38abk07iqdg&usg = afqjcnhcifqrutxkquvlrcgoaqkscaltha&sig2 = g8yn7ie1pbzske2mfvv41bw&cad = rja = rja = rja

希望这能给您一些见识。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top