Расшифровать билет kerberos с помощью Spnego

Я использую spnego (http://spnego.sourceforge.net) для проверки подлинности kerberos в JBoss.

Мне нужно расшифровать билет kerberos для доступа к данным авторизации, которые будут содержать данные PAC. Данные PAC необходимы, чтобы решить, какие роли должны быть предоставлены пользователю.

Как получить доступ и расшифровать билет Kerberos? Я искал в сети примеры, но без усилий.

5 ответов


эти ребята имеют полную реализацию декодирования 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. Не уверен, что тебе это нужно.

Грант


Я успешно использовал фильтр сервлетов из 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, который раскрывает LogonInfo через getUserPrincipal().

пример проекта демонстрирует приведенный выше код в полный можно найти здесь:

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

фильтр spnego-pac (используется в приведенном выше примере) можно найти здесь:

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

надеюсь, что это полезно для всех.

__
Марсель!--6-->


если вы получаете токен механизма от spnegoToken такой:

byte[] mechanismToken = spnegoToken.getMechanismToken(); 

маркер механизма обычно является KerberosApRequest. Есть KerberosToken конструктор, который принимает KerberosApRequest. Просто пройдите в mechanismToken массив байтов вместе с ключом для расшифровки содержимого.


Я предоставляю свое собственное решение проблемы:

Я основал свое решение на библиотеке BouncyCastle (для разбора частей токена) и JaasLounge (для расшифровки зашифрованной части токена). К сожалению, код для декодирования всего токена spnego из JaasLounge не соответствовал моим требованиям. Я должен был написать его сам.

Я декодировал билет по частям, сначала построив DERObjects из массива byte []:

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

Вау было некоторое время, так как я использовал spnego (почти год) ... Ты задаешь очень крутой вопрос.

Я немного покопался и собирался попробовать запустить какой-то код, который у меня был некоторое время назад, который работал с MS-AD, но просто не чувствовал его сегодня: -/

в любом случае, я нашел эту ссылку через гуглить: 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=g8yn7ie1PbzSkE2Mfv41Bw&cad=rja

надеюсь, это может дать вам некоторое представление.