Subject Re: JWT Signing
From Regan Cawkwell <regan@rbauk.com>
Date Wed, 2 Oct 2019 10:42:15 +0100
Newsgroups xb2net


Hi Jack

Just for reference, the Chilkat library has butil-in options for handling these using
different encruptions.

Sorry I missed the earlier post.

Regan

On 01/10/2019 23:52, Jack Duijf wrote:
> 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 Jack Duijf 01-Oct-2019 06:52 pm
..\# Re: JWT Signing (Current message) Regan Cawkwell 02-Oct-2019 05:42 am