Subject JWT Signing
From Jack Duijf <jack@ldsoftware.nl>
Date Mon, 30 Sep 2019 21:40:50 +0200
Newsgroups xb2net


Hello,

I need to exchange data with an external webserver using JWT.  (Json Web Token)
header.payload.signing

The header looks like:  {"alg" : "HS256","typ" : "JWT"}

Using SHA256 hash only does not work. There is also a 32 byte secret key.
How to create/verify the correct secure signing in xb2net?

Below the Java code they sent me...
I can not make head or tails from it.

Regards,
Jack Duijf


package com.mycompany.protocol.testhost;

import java.security.InvalidKeyException;
import java.security.SignatureException;
import java.util.Calendar;
import java.util.List;

import net.oauth.jsontoken.JsonToken;
import net.oauth.jsontoken.JsonTokenParser;
import net.oauth.jsontoken.crypto.HmacSHA256Signer;
import net.oauth.jsontoken.crypto.HmacSHA256Verifier;
import net.oauth.jsontoken.crypto.SignatureAlgorithm;
import net.oauth.jsontoken.crypto.Verifier;
import net.oauth.jsontoken.discovery.VerifierProvider;
import net.oauth.jsontoken.discovery.VerifierProviders;

import org.joda.time.DateTime;

import com.google.common.collect.Lists;
import com.google.gson.JsonObject;

/**
* Provides static methods for creating and verifying access tokens and such.
*
* @author davidm
*
*/
public class AuthHelper {

        private static byte[] key256 = {0x08, 0x02, 0x30, 0x25, 0x09, 0x10, 0x50,
                        0x01, 0x2a, 0x2a, 0x2d, 0x42, 0x55, 0x49, 0x4c, 0x4a, 0x41, 0x43,
                        0x4f, 0x47, 0x45, 0x2d, 0x2a, 0x2d, 0x2d, 0x2a, 0x2f, 0x42, 0x55,
                        0x49, 0x42, 0x44, 0x41, 0x43, 0x4f, 0x44, 0x45, 0xa1, 0x2a, 0x2d,
                        0x08, 0x08, 0x30, 0x25, 0x09, 0x10, 0x50, 0x01, 0xb6, 0x02, 0x30,
                        0x25, 0xa2, 0x10, 0x50, 0x01, 0x2d, 0x2a, 0x2d, 0x42, 0x55, 0x49,
                        0x4c, 0x21, 0x41, 0x43, 0x4f, 0x44, 0x45, 0x2d, 0x2a, 0x2d, 0x2d,
                        0x2a, 0x2a, 0x42, 0x55, 0x49, 0x4c, 0x44, 0x41, 0x43, 0x4f, 0x44,
                        0x45, 0x2f, 0x2a, 0x2d, 0x08, 0x02, 0x30, 0x25, 0x09, 0x10, 0x50,
                        0x01};

        public class TokenInfo {
                private String subject;
                private DateTime issued;
                private DateTime expires;

                public String getSubject() {
                        return subject;
                }

                public void setSubject(String Subject) {
                        this.subject = Subject;
                }

                public DateTime getIssued() {
                        return issued;
                }

                public void setIssued(DateTime issued) {
                        this.issued = issued;
                }

                public DateTime getExpires() {
                        return expires;
                }

                public void setExpires(DateTime expires) {
                        this.expires = expires;
                }
        }

        private static final String AUDIENCE = "UserId";
        private static String ISSUER = "My Company";
        private String SIGNING_KEY = new String(key256);

        /**
         * set the master key
         */
        public void SetMasterKey() {
                SIGNING_KEY = new String(key256);
                // LogAgent.sLogEvent(1, 1, "== MasterKey == ");
        }
        /**
         * set the session key
         *
         * @param fKey
         */
        public void SetSessionKey(String fKey) {
                SIGNING_KEY = fKey;
                // LogAgent.sLogEvent(1, 1, "== SessionKey = " + SIGNING_KEY);
        }

        /**
         *
         * @param args
         */
        public static void main(String args[]) {
                AuthHelper ah = new AuthHelper();
                String t = ah.createJsonWebToken("Login", (long) 1);
                System.out.println("[" + t + "]");
        }

        /**
         * update issuer for communication
         *
         * @param fIssuer
         */
        public void setIssuer(String fIssuer) {
                ISSUER = fIssuer;
        }

        /**
         * Creates a json web token which is a digitally signed token that contains
         * a payload (e.g. userId to identify the user). The signing key is secret.
         * That ensures that the token is authentic and has not been modified. Using
         * a jwt eliminates the need to store authentication session information in
         * a database.
         *
         * @param subject
         * @param durationDays
         * @return
         */
        public String createJsonWebToken(String subject, Long durationDays) {
                // Current time and signing algorithm
                Calendar cal = Calendar.getInstance();
                HmacSHA256Signer signer;
                try {
                        signer = new HmacSHA256Signer(ISSUER, null, SIGNING_KEY.getBytes());
                } catch (InvalidKeyException e) {
                        throw new RuntimeException(e);
                }

                // Configure JSON token
                JsonToken token = new net.oauth.jsontoken.JsonToken(signer);
                token.setAudience(AUDIENCE);
                token.setIssuedAt(new org.joda.time.Instant(cal.getTimeInMillis()));
                token.setExpiration(new org.joda.time.Instant(cal.getTimeInMillis()
                                + 1000L * 60L * 60L * 24L * durationDays));
                token.setParam("sub", subject);
                JsonObject payload = token.getPayloadAsJsonObject();
                try {
                        return token.serializeAndSign();
                } catch (SignatureException e) {
                        throw new RuntimeException(e);
                }
        }

        /**
         * Verifies a json web token's validity and extracts the user id and other
         * information from it.
         *
         * @param token
         * @return
         * @throws SignatureException
         * @throws InvalidKeyException
         */
        public TokenInfo verifyToken(String token) {
                try {
                        final Verifier hmacVerifier = new HmacSHA256Verifier(
                                        SIGNING_KEY.getBytes());

                        VerifierProvider hmacLocator = new VerifierProvider() {

                                @Override
                                public List<Verifier> findVerifier(String id, String key) {
                                        return Lists.newArrayList(hmacVerifier);
                                }
                        };
                        VerifierProviders locators = new VerifierProviders();
                        locators.setVerifierProvider(SignatureAlgorithm.HS256, hmacLocator);
                        net.oauth.jsontoken.Checker checker = new net.oauth.jsontoken.Checker() {

                                @Override
                                public void check(JsonObject payload) throws SignatureException {
                                        // don't throw - allow anything
                                }

                        };
                        // Ignore Audience does not mean that the Signature is ignored
                        JsonTokenParser parser = new JsonTokenParser(locators, checker);
                        JsonToken jt;
                        try {
                                jt = parser.verifyAndDeserialize(token);
                        } catch (SignatureException e) {
                                throw new RuntimeException(e);
                        }
                        JsonObject payload = jt.getPayloadAsJsonObject();
                        TokenInfo t = new TokenInfo();
                        String issuer = payload.getAsJsonPrimitive("iss").getAsString();
                        // BNG: update it with the information from the web socket server
                        ISSUER = issuer;
                        String subjectString = payload.getAsJsonPrimitive("sub")
                                        .getAsString();
                        // if (issuer.equals(ISSUER) && !userIdString.isEmpty()) {
                        if (!subjectString.isEmpty()) {
                                t.setSubject(subjectString);
                                t.setIssued(new DateTime(payload.getAsJsonPrimitive("iat")
                                                .getAsLong()));
                                t.setExpires(new DateTime(payload.getAsJsonPrimitive("exp")
                                                .getAsLong()));
                                return t;
                        } else {
                                return null;
                        }
                } catch (InvalidKeyException e1) {
                        throw new RuntimeException(e1);
                }
        }
}

Recent messages in this thread
 
-# JWT Signing (Current message) Jack Duijf 30-Sep-2019 03:40 pm
.-# Re: JWT Signing Jack Duijf 01-Oct-2019 06:52 pm
..\# Re: JWT Signing Regan Cawkwell 02-Oct-2019 05:42 am