Die JavaDoc für signWith(SignatureAlgorithm var1, String var2)
gibt Erwartungen, und die Methodenparameter intuitiv sogar Namen:
/**
* Signs the constructed JWT using the specified algorithm with
* the specified key, producing a JWS.
*
* <p>
* This is a convenience method: the string argument is first
* BASE64-decoded to a byte array and this resulting byte array is
* used to invoke {@link #signWith(SignatureAlgorithm, byte[])}.
* </p>
*
* @param alg the JWS algorithm to use to digitally
* sign the JWT, thereby producing a JWS.
*
* @param base64EncodedSecretKey the BASE64-encoded algorithm-specific
* signing key to use to digitally sign
* the JWT.
*
* @return the builder for method chaining.
*/
JwtBuilder signWith(SignatureAlgorithm alg, String base64EncodedSecretKey);
Also, diese Methode der String-Argument erwartet eine Base64-codierte Geheimschlüssel Byte-Array zu sein. Es nicht eine allgemeine Zeichenfolge, wie ein Benutzerkennwort zum Beispiel als Signierschlüssel annehmen. JJWT geht von der Base64-Kodierung aus, da Sie, wenn Sie ein Zeichenfolgenkennwort angeben, das nicht Base64-kodiert ist, wahrscheinlich einen schlecht formatierten oder schwachen Schlüssel verwenden.
Die JWT-JWA-Spezifikation REQUIRES, dass HMAC-Signaturschlüssel Längen gleich oder größer als die Signatur Byte-Array-Länge haben.
Das bedeutet, dass:
| If you're signing with: | your key (byte array) length MUST be: |
| ----------------------- | ------------------------------------- |
| HMAC SHA 256 | >= 256 bits (32 bytes) |
| HMAC SHA 384 | >= 384 bits (48 bytes) |
| HMAC SHA 512 | >= 512 bits (64 bytes) |
Viele Online JWT Websites und Tools nur gerade diese Ebene falsch - sie ermöglichen es Ihnen zu denken, dass Sie in oder eine alte Zeichenfolge verwenden geben könnte und du bist gut. Einige gehen sogar so weit, den Schlüssel mit dem Wort secret
vorzufüllen (eindeutig eine schlechte Idee und nicht einmal spezifikationskonform, weil es zu kurz ist!).
Damit Sie dies vereinfachen können, bietet JJWT ein Hilfsprogramm, mit dem Sie genügend sichere Zufallsschlüssel generieren können, die für die spezifikationskonforme Signatur über die Klasse io.jsonwebtoken.impl.crypto.MacProvider
geeignet sind.
Sehen Sie sich die verschiedenen generateKey
Methoden an, um zu sehen, wie Sie einen guten, spezifikationskonformen Schlüssel für HMAC-Signaturen generieren können. Zum Beispiel:
//creates a 256-bit secure-random key:
MacProvider.generateKey(SignatureAlgorithm.HS256);
//creates a 384-bit secure-random key:
MacProvider.generateKey(SignatureAlgorithm.HS384);
//creates a 512-bit secure-random key (the default):
MacProvider.generateKey();
Wenn Sie diese generierten Schlüssel als String speichern wollten, könnten Sie vermutlich Base64 kodieren sie:
SecretKey key = MacProvider.generateKey();
byte[] keyBytes = key.getEncoded();
String base64Encoded = TextCodec.BASE64.encode(keyBytes);
Aber Anmerkung: die resultierende base64Encoded
String nicht als sicher jemandem zeigen. Die Base64-Codierung ist keine Verschlüsselung - der Wert muss weiterhin geheim gehalten werden. Wie Sie dies tun, liegt bei Ihnen (verschlüsseln Sie es, usw.).
Nun, wenn es Zeit ist, eine JWS zu erstellen, können Sie in diesem base64Encoded
Wert nur passieren, und JJWT wissen zu Base64 dekodieren es zuerst die realen Bytes zu erhalten, die dann dazu verwendet werden, um die Signatur zu berechnen:
Jwts.builder()
//...
.signWith(SignatureAlgorithm.HS512, base64Encoded)
.compact();
Sicherheit weise (extreme Maßnahmen), sagt diese Antwort Strings sind weniger gesichert (kurz, wegen String-Pool): http://StackOverflow.com/A/8881376/641627 – alexbt