01-09-23 02:39 PM
Hi - a project that I am currently working on requires the use of the Blue Prism supported JWT VBO. I need to generate a JWT token using the RSA256 method.
After importing the VBO into my environment, I have 26 errors (please see screenshot). I suspect that this is because of the pre-requisite assemblies (DLLs) that are required from Nuget.
Is my assumption correct? Are the 3 assemblies listed below the correct ones? And if so, how do I install these onto the Blue Prism virtual machines?
Finally, looking at the code stage for generating a token using RSA256, I see no reference to headers, just the input 'payload' (collection of claims). Is this sufficient? I understand the target system requiring a JWT token requires certain values in the headers.
01-09-23 08:08 PM
Hi Jack,
Yes, that JWT object relies on some extra libraries that need to be downloaded and placed in a location where Blue Prism can find them when this JWT object calls for them. These libraries can be downloaded from Nuget which is the main source for these kinds of libraries that are needed for Windows and .NET software. Each Nuget page linked below has a "Download Package" button. This will download a file that ends with a .nupkg extension. Change this to .zip so you can unzip and get to the library file inside which will be a .dll file.
For each .dll file you extract from each of these packages, place it in your Blue Prism program folder which should be in one of two places on the computer:
BouncyCastle
URL: https://www.nuget.org/packages/BouncyCastle.Crypto.dll
Location: /lib/BouncyCastle.Crypto.dll
JWT
URL: https://www.nuget.org/packages/JWT
Location: /lib/net462/JWT.dll
System.IdentityModel.Tokens.Jwt
URL: https://www.nuget.org/packages/System.IdentityModel.Tokens.Jwt/7.0.0-preview4
Location: /lib/net472/System.IdentityModel.Tokens.Jwt.dll
Microsoft.IdentityModel.Tokens
URL: https://www.nuget.org/packages/Microsoft.IdentityModel.Tokens/7.0.0-preview4
Location: /lib/net472/Microsoft.IdentityModel.Tokens.dll
Microsoft.IdentityModel.Abstractions
URL: https://www.nuget.org/packages/Microsoft.IdentityModel.Abstractions/7.0.0-preview4
Location: /lib/net472/Microsoft.IdentityModel.Abstractions.dll
In regards to the headers that are part of a JWT token, the code stage (along with the libraries) should take care of that automatically. I believe the header is typically just the token type and algorithm, so passing in your set of claims for the payload should be sufficient.
07-09-23 10:18 AM
@charliekovacs thanks for your response. That has removed our compiler errors.
I am able to generate a private key, public key etc and read these into Blue Prism.
However, when running the 'Generate RS256 Token' action, I get the following error message:
07-09-23 03:08 PM
I suspect it is down to needing a different version of the JWT library other than what I linked above - I had not considered this, so here is what I suggest trying:
JWT v10.1.0 needs Newtonsoft.Json v13 whereas JWT v9.0.3 only needs Newtonsoft.Json v10 or later, so I am hopeful the arrangement I am suggesting makes all of these libraries work together as they are supposed to.
07-09-23 04:30 PM
Thank you for your response - I followed those steps (installed an older version of JWT) and that has got my JWT token creation working.
I have a follow-on issue/question however:
When I generate a private/public key pair within the VBO itself, I am able to run the Generate JWT (RS256) action with no issues.
However, the target system requires that I generate an X509 certificate with corresponding public key. This looks simple using OpenSSL, but is there any way this can be supported within Blue Prism?
I can see a 'Create X509 Certificate' action in the Blue Prism JWT VBO, but I cannot configure it to work successfully. Do you know how to resolve this error?
To prove the concept, I separately tried generating the private key manually using openssl then inputting into Blue Prism. The private key looks like this in structure (obviously with several rows removed for security purposes)
07-09-23 07:59 PM
Hi @JackLeyland
I believe the Generate JWT (RS256) action is looking for a slightly different private key file format - specifically RSA. Here is an example:
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEArh8F9RUrlscndS8S...
-----END RSA PRIVATE KEY-----
The only different is it states RSA Private Key instead of just Private Key. The Generate RSA Keypair action can create this and OpenSSL can do it, too, as you mentioned. I was able to do it with OpenSSL using the following set of commands:
openssl genrsa -out private-key.pem 2048
openssl rsa -in private-key.pem -pubout -out public-key.pem
openssl eq -new -x509 -key private-key.pem -out cert.pem -days 360 -subj "/C=US/ST=Texas/L=Austin/O=example/CN=example"
To do this in Blue Prism, I recommend the Utility - Environment object as I do not think the X509 action in the JWT object works in its current state. Use the Run Process Until Ended action which has four inputs:
openssl.exe
on your computer.genrsa -out private-key.pem 2048
C:\Users\me\Desktop\
(I think the trailing backslash is required)
So, my advice is to make sure your OpenSSL commands work first and that it generates a good RSA private key file that the Generate JWT (RS256) action accepts. And then use the Utility - Environment object to automate those OpenSSL commands in your process.
08-09-23 02:13 PM
@charliekovacs thanks again, I appreciate your help on this.
I have been able to progress further and now have a working 'pipeline' of steps
I have one final challenge. The target system dictates that I need specific values in the 'headers' for my token. As previously mentioned these are auto-generated and not editable using the existing input parameters in the VBO.
Currently the headers are auto-generated as follows, but I need one more attribute 'kid'.
Do you know how I would be able to amend this? I assume it will require some manipulation of the (global) code?
Many thanks
Jack
08-09-23 06:14 PM
Hi @JackLeyland
Yes, that should be doable with a slight adjustment to the code stage on the Generate JWT (RSA256) action.
1) Create a new data item to store the KID value (data type: Text). Add it as an input value on the Start parameters
2) Open the Generate JWT code stage. On the Inputs tab, create an entry for this KID Value data item and give it a name of KidValue
3) Switch to the Code tab and update as follows:
a) Remove Line 34: Token = encoder.Encode(payload, privateKey);
b) Paste this block of code in, starting on Line 34:
if (string.IsNullOrEmpty(KidValue))
{
Token = encoder.Encode(payload, privateKey);
}
else
{
var kidHeader = new Dictionary<string, object>{{"kid", KidValue}};
Token = encoder.Encode(kidHeader, payload, privateKey);
}
It should look like this:
Click the Check Code button to make sure no errors are found with this update, save the VBO, and then it should work. When you run this action from a process, pass in a value to the KID Value input and it will include it in the JWT header. If you leave KID Value blank, it will leave it out of the header, so this makes it flexible.
If you need to use any of the other JWT actions besides Generate JWT (RSA256), I think you would need to repeat these steps in those other action pages as well.
I did not fully test the JWT token this produces against a system or anything, but I inspected it and it looks to be formatted correctly: {"kid":"example-kid-value","typ":"JWT","alg":"RS256"}
Let me know if this works. I will look into possibly making this an official update to the JWT object.
11-09-23 08:54 AM
@charliekovacs wonderful thanks again for your response. Include KID in the header works perfectly as described, thank you!
Just going back a couple of messages: I followed the steps to generate a key pair and X509 certificate using OpenSSL. This worked okay but still I was not able to generate a RS256 JWT token using the OpenSSL-generated private key. I could only get JWT token generation to work with the private key if generated within BP using BouncyCastle.
The initial error was as follows:
Internal : Could not execute code stage because exception thrown by code stage: Could not read RSA private key
I suspected (as you mentioned), this is because the header of the private key was '-----BEGIN PRIVATE KEY-----', whereas generating within the JWT VBO using BouncyCastle creates private key beginning with '-----BEGIN RSA PRIVATE KEY-----'.
I tried adding 'RSA' to the key header (and footer) to see if this resolved it, but then I get a new error:
ERROR: Internal : Could not execute code stage because exception thrown by code stage: malformed sequence in RSA private key
Have you been able to get a working pipeline of steps where you:
Given the requirements of the target system, this is what we need to configure. Many thanks in advance. Almost there.
11-09-23 05:19 PM
Hi @JackLeyland
I attached an example process that is working for me. The steps are:
1) Generate RSA private key file with openssl.exe
Command: openssl.exe genrsa -out private-key.pem 2048
This creates an RSA (2048 size) private key in a file named private-key.pem that has the -----BEGIN RSA PRIVATE KEY-----
header (and footer). If it does not, then something is incorrect here. Running cat private-key.pem
after this command runs is an easy way to see the file that was created properly.
2) Extract RSA public key with openssl.exe
Command: openssl.exe rsa -in private-key.pem -pubout -out public-key.pem
Using the private-key.pem file from the previous step, this command creates a public-key.pem file that contains the associated public key.
3) Generate X.509 certificate with openssl.exe
Command: openssl.exe req -new -x509 -key private-key.pem -out cert.pem -days 365 -subj "/C=US/ST=Texas/L=Austin/O=example/CN=example"
This creates a certificate file called cert.pem. The -days
argument lets you set the expiration in number of days and the -subj
argument lets you set the organization details, so you can edit those values as needed.
4) Generate JWT with VBO
This step is where the Utility - JWT VBO generates the token using the private-key-pem file created in step 1. It will output a Token value. I tested it at https://jwt.io and when I pasted the token along with either the public-key.pem contents or the cert.pem contents, it all showed up as validated correctly. Hoping you find the same!
I can suggest running the openssl.exe commands in a Command Prompt first (recommended Run as Administrator for the command prompt). If you can get each command to run successfully, then try running the attached process in Blue Prism. Make sure to check the input parameters for each stage as well as the input data items - specifically the [Application Path] and [Working Folder] because those might be different between my computer and yours.