簡體   English   中英

使用Spnego解密kerberos票

[英]Decrypt kerberos ticket using Spnego

我正在使用spnego( http://spnego.sourceforge.net )在JBoss下進行kerberos身份驗證。

我需要解密kerberos票證才能訪問包含PAC數據的授權數據。 需要PAC數據來決定將哪些角色授予用戶。

如何訪問和解密kerberos票? 我在網上搜索了一些例子,但沒有努力。

我已成功使用http://spnego.sourceforge.net中的servlet過濾器與http://jaaslounge.sourceforge.net/中的PAC解析器結合使用,而無需使用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

希望這對任何人都有幫助。

__
馬塞爾

這些人有完整的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票證,您將需要跳過一些箍。 不確定你是否需要它。

格蘭特

我提供了自己的問題解決方案:

我的解決方案基於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);

我們從客戶端瀏覽器接收的字節序列將被解析為單個DERApplicationSpecific,它是票根 - 級別0。
根包含:

  • DERObjectIdentifier - SPNEGO OID
  • DERSequence - 1級

1級包含:

  • DERObjectIdentifier的序列 - 機械類型
  • DEROctetString - 包裹DERApplicationSepecific - 級別2

2級包含:

  • DERObjectIndentifier - Kerberos OID
  • KRB5_AP_REQ標記0x01 0x00 ,解析為布爾值(false)
  • DERApplicationSpecific - DERSequence的容器 - 級別3

3級包含:

  • 版本號 - 應為5
  • 消息類型 -​​ 14(AP_REQ)
  • AP選項(DERBITString)
  • DERApplicationSpecific - 包含票證部分的DERSequence
  • DERSeqeuence與額外的票證部分 - 未處理

機票部分 - 第4級包含:

  • 機票版本 - 應為5
  • 票證領域 - 用戶通過身份驗證的領域的名稱
  • 服務器名稱的后綴。 每個服務器名稱是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];
}

如果你從spnegoToken獲得機制令牌,如下所示:

byte[] mechanismToken = spnegoToken.getMechanismToken(); 

機制令牌通常是KerberosApRequest 有一個KerberosToken構造函數,它接受KerberosApRequest 只需傳入mechanismToken字節數組和密鑰即可解密內容。

自從我使用了spnego(將近一年)以來已經有一段時間......你問的是一個非常酷的問題。

我做了一點挖掘,並嘗試運行一些我曾經使用MS-AD的代碼,但今天感覺不到: - /

無論如何,我通過谷歌找到了這個鏈接: http//www.google.com/url? sa = t&source = web&cd = 1&sqi = 2&ed = 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 = g8yn7ie1PbzSkE2Mfv41Bw及CAD = RJA

希望這可以給你一些見解。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM