Subject Re: JWT Signing
From Jack Duijf <jack@ldsoftware.nl>
Date Wed, 02 Oct 2019 00:52:20 +0200
Newsgroups xb2net

Hello,

I eventualy managed to write Xbase++ code for this.

Jack


On Mon, 30 Sep 2019 21:40:50 +0200, Jack Duijf <jack@ldsoftware.nl> wrote:

>
>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 Jack Duijf 30-Sep-2019 03:40 pm
.-# Re: JWT Signing (Current message) Jack Duijf 01-Oct-2019 06:52 pm
..\# Re: JWT Signing Regan Cawkwell 02-Oct-2019 05:42 am