2017-04-25 3 views
0

Ich habe eine jhipster Spring-Boot-Anwendung, die ein Token von einer dritten Partei, die mit unserem öffentlichen Schlüssel verschlüsselt wurde, akzeptiert akzeptiert. Ich habe einen JWTFilter, der das Token mit unserem privaten Schlüssel entschlüsselt und ein Authentifizierungsobjekt erstellt, das im Sicherheitskontext gespeichert wird. Sobald die Ausführung den Controller erreicht, beabsichtige ich, den Benutzernamen und das Passwort aus dem Sicherheitskontext zu ziehen, damit ich API-Aufrufe zurück an die Drittanbieteranwendung senden kann.JWT entschlüsselt, aber wirft einen Mac-Check Fehler fehlgeschlagen

Dies funktioniert bis zu einem gewissen Grad in unserer Integrationsumgebung, wo der Drittanbieter eine Verbindung zu einer laufenden Instanz unserer Anwendung hat. Um lokal zu testen, treffe ich den Link in der Integrationsumgebung und kopiere das Token. Dann mache ich eine Anfrage von Postman an eine Instanz unserer Anwendung, die ich lokal mit dem in den Kopfzeilen hinzugefügten Token ausführe, genau wie unser js-Client.

Ich verwende "com.nimbusds: nimbus-jose-jwt: 4.23" für die Entschlüsselung, und ich bekomme einen Fehler "MAC-Prüfung fehlgeschlagen". Ich kann den Wert von macCheckPassed im Debugger auf "true" setzen und die Entschlüsselung wird abgeschlossen, sodass ich die Ansprüche sehen und in den Sicherheitskontext laden kann. Ein anderer Filter fängt jedoch meinen Hack ab und die Anfrage wird mit einem Autorisierungsfehler abgewiesen.

public static byte[] decryptAuthenticated(final SecretKey secretKey, 
             final byte[] iv, 
             final byte[] cipherText, 
             final byte[] aad, 
             final byte[] authTag, 
             final Provider ceProvider, 
         final Provider macProvider) 
    throws JOSEException { 


    // Extract MAC + AES/CBC keys from input secret key 
    CompositeKey compositeKey = new CompositeKey(secretKey); 

    // AAD length to 8 byte array 
    byte[] al = AAD.computeLength(aad); 

    // Check MAC 
    int hmacInputLength = aad.length + iv.length + cipherText.length + al.length; 
    byte[] hmacInput = ByteBuffer.allocate(hmacInputLength). 
     put(aad). 
     put(iv). 
     put(cipherText). 
     put(al). 
     array(); 
    byte[] hmac = HMAC.compute(compositeKey.getMACKey(), hmacInput, macProvider); 

    byte[] expectedAuthTag = Arrays.copyOf(hmac, compositeKey.getTruncatedMACByteLength()); 

    boolean macCheckPassed = true; 

    if (! ConstantTimeUtils.areEqual(expectedAuthTag, authTag)) { 
     // Thwart timing attacks by delaying exception until after decryption 
     macCheckPassed = false; 
    } 

    byte[] plainText = decrypt(compositeKey.getAESKey(), iv, cipherText, ceProvider); 

    if (! macCheckPassed) { 

     throw new JOSEException("MAC check failed"); 
    } 

    return plainText; 
} 

Was ist dieser MAC-Check? Ich dachte, es hätte mit der Herkunft des Tokens zu tun. Etwas in der Art, wie das Token mit der MAC-ID des Quellsystems verschlüsselt wird, was zu einem Fehler führt, wenn es nicht mit meinem aktuellen Host synchronisiert wird.

Welcher andere Filter würde die Anfrage ablehnen, wenn die Entschlüsselung erfolgreich war? Gibt es ein anderes Flag, das ich einstellen soll, damit das Framework die Anfrage berücksichtigt?

Antwort

1

JWE Spezifikationen Mandate authenticated encryption, um sicherzustellen, dass der Klartext nicht nur verschlüsselt, sondern auch gegen Manipulationen geschützt ist. Um sicherzustellen, dass ein HMAC is applied nach der Inhaltsverschlüsselung.

Der Fehler "Mac check failed" kann zwei Dinge bedeuten - die Bibliothek, die den ursprünglichen JWE/JWT erzeugt hat, hat den HMAC falsch angewendet, oder der JWE/JWT wurde während des Transports geändert.

Verwandte Themen