i would need to validate a token with jwt.io
To do this I have a token (license)
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZW5hbnRJZCI6MjcwMzYwLCJwYWNrYWdlc.........."
and a json (certificate)
"keys": [
{
"kid": "1",
"e": "AQAB",
"kty": "RSA",
"alg": "RS256",
"n": "rXYc2Ehtb42R83kLIw56biI/ABOp03lzbYHdXI0caeli.......",
"use": "sig"
}
inside the debugger of the jwt.io site with this information I receive that the "signature is verified".
I'm looking for some scripts on the net that can allow me to do the same thing
Same on the jwt.io site I find that I can use the code reported here https://github.com/PhilJay/JWT which, however, if I understand correctly, does not use the RS256 algorithm but ES256 and therefore should not work.
I'm trying the same but honestly I don't understand what the decoder is asking for in the example
val valid = JWT.verify (tokenString, jwk, decoder)
the first two I believe are the data I have.
can you give me some suggestions or give me some other code to verify the signature?
The problem is here
val nInt = Biginteger(1, Base64.getUrlDecoder().decode(n))
You have to take only the element n of cert and not all cert(json)
val e = obj_cert.asJsonObject["e"].asString
val n = obj_cert.asJsonObject["n"].asString.replace('+', '-').replace('/', '_').replace("=", "")
val eInt = BigInteger(1, Base64.getUrlDecoder().decode(e))
val nInt = BigInteger(1, Base64.getUrlDecoder().decode(n))
val spec = RSAPublicKeySpec(nInt, eInt)
val publicKey = KeyFactory.getInstance("RSA").generatePublic(spec) as RSAPublicKey
val algorithm: Algorithm = Algorithm.RSA256(publicKey, null)
val verifier: JWTVerifier = com.auth0.jwt.JWT.require(algorithm).build()
verifier.verify(license)
Related
I am trying to create a JWE Token using the node-jose library's createEncrypt method. The problem is, I want to set the kid to a certain value. But when importing the key using the jose.JWK.asKey method, it's automatically calculating the kid and won't let me change/set it. Here is the sample code:
const { JWK, JWE } = require('node-jose');
encrypt = async (raw, format = 'compact', contentAlg = "A128CBC-HS256", alg = "RSA-OAEP-256") => {
let _publicKey = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxO+O52a1eAkbYatqpPAk
vhTz5VAdNloWhbmAmwPQl9202VKxU+yOCbwZSU8NqwVubHMgnxdycgJw+zGslXgz
zHPpmA5evOY2AVjpcE9avKfp523M5gxOaAnQCxat6KxORIJWLSF84EUtrzLIxgle
bvDyhfoHMGVSYiP89UQPTR+uu6irFRkdu2zFDPOx2/4XdtyAbJlWdj4Fes0v3CcA
/jDO9EmwVEiySCuagLWnrvHvCV0mCDN167JSVjeeKZy4Q36WyF0VqytxmW+mXn+m
IfcLlj5vXSXp81pI1Iyg86KZtW3A6dP8QuRlYwHJU7Z+m7AeIHtC+ol0/eBPYPwk
PQIDAQAB
-----END PUBLIC KEY-----`
let publicKey = await JWK.asKey(_publicKey, "pem");
publicKey.kid = "932ea6bb-2623-4dc3-96b1-c4be61e97569";
console.log(publicKey)
const buffer = Buffer.from(JSON.stringify(raw))
const encrypted = await JWE.createEncrypt({ format: format, contentAlg: contentAlg, fields: { alg: alg, iat: (new Date().getTime()), exp: 30000} }, publicKey)
.update(buffer).final();
return encrypted;
}
let raw = {
"mobileNumber": "1234567890",
"customerId": "000000000",
"sessionId": "3a600342-a7a3-4c66-bbd3-f67de5d7096f",
};
encrypt(raw).then((data)=> {console.log(data)})
Here is the encrypted JWE Token generated:
eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJpYXQiOjE2NDAyNDU0NzY5ODEsImV4cCI6MzAwMDAsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJraWQiOiI1bUxtdmVHdng0RHVucGlfTnBhajhxZlByRHNDYW9NV29JeWRoM003SzA4In0.SUpO7X0XXbkqQtNGVvLMNo6oGi1GrTzAR1FtXlL8ngg9Uvd91nkLiRqgcmjKBBEE1M330WV_HrUYNs2NVRcXTDcr41fSwvHSu7veK_YDj-m73LoMKlmojeB6GIRUIXIw7oaqgFSOSb_Xgq_zwG9WGa07h2OgOzeFxKNJCvt1J2i_v2Tt61yyet0hdMinT78whDGgf_JW4LUSaXY9wsqsuQSDkKWFLvxHqNmq7nGPLpgEJjm1GPF0slPvdWsARsMEttbPK9VpoMUvMcqy5bWVWSmj2MEGTVw6ua-uFw9fEgyn095wl-s8lEfZFkFaiFN7ps5VwqVV2tihpnYrCVIYAA.jxR4Gw_Gcy9Sexw-wMBKtQ.TzugQZCFgQiolIBc2FAEQ0ZbvNdPFzE2z0m9cFxWQtADEijOCzQjZreVvnsVjHFXdP_w-YcnCbmKXkwalWnFMo7wkjuuJ0fAsTfTOEiBjuIPvMa0k04C97Rc4ZYszzzL7xxwW0RnqoNxiQMkea3H0A.qAqgcg_DLV1vHzb0EIq-9A
If you check this on jwt.io, you can see the kid is already calculated & set. How can I set/change the kid here?
The kid is calculated automatically, when it's not known during the import:
When importing or generating a key that does not have a "kid" defined, a "SHA-256" thumbprint is calculated and used as the "kid".
(see https://github.com/cisco/node-jose#obtaining-a-keys-thumbprint)
But in the call to JWK.asKey, you can pass an additional parameter extras, that sets values for existing fields or contains additional fields for the JWK.
For your use case, you can set a kid as a JSON object
let kid = "932ea6bb-2623-4dc3-96b1-c4be61e97569";
let publicKey = await JWK.asKey(_publicKey, "pem", {"kid":kid});
console.log(publicKey.toJSON())
Output:
{
kty: 'RSA',
kid: '932ea6bb-2623-4dc3-96b1-c4be61e97569',
n: 'xO-O52a1eAkbYatqpPAkvhTz5VAdNloWhbmAmwPQl9202VKxU-yOCbwZSU8NqwVubHMgnxdycgJw-zGslXgzzHPpmA5evOY2AVjpcE9avKfp523M5gxOaAnQCxat6KxORIJWLSF84EUtrzLIxglebvDyhfoHMGVSYiP89UQPTR-uu6irFRkdu2zFDPOx2_4XdtyAbJlWdj4Fes0v3CcA_jDO9EmwVEiySCuagLWnrvHvCV0mCDN167JSVjeeKZy4Q36WyF0VqytxmW-mXn-mIfcLlj5vXSXp81pI1Iyg86KZtW3A6dP8QuRlYwHJU7Z-m7AeIHtC-ol0_eBPYPwkPQ',
e: 'AQAB'
}
import requests
import json
url = "********"
payload = json.dumps({
"username": "*****",
"password": "*****"
})
headers = {
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
#*** Convert response into a dictionary ***
r = json.loads(response.text)
# *** print the value of they key 'accessToken'
bearerToken = r['accessToken']
print(bearerToken)
Output
{'accessToken': 'e************************************', 'tokenType': 'Bearer'}
What am I trying to achieve?
Grab only the censored code after 'accessToken' and store the new Access Token in a string to use it in HTTP requests.
Note: 'accessToken' is a value of another key called accessToken. So the traditional method of printing the value of the key has already been used in the output shown above.
Complete output:
{
"accessToken" : {
"accessToken" : "e******************",
"tokenType" : "Bearer"
},
"refreshToken" : {
"id" : "6*************",
"lastAccessedTime" : 1***********,
"refreshToken" : "e*************"
}
}
In Python, you can use substrings to accomplish what you want. If the length of the prefix is constant, then all you would need to do is use a slice with constant index,
In your example, it looks like you have an accessToken key, and inside that key is another dictionary holding a key that can change between entries. Assuming that you want the censored portion after e in accessToken, you can access that using:
bearerToken = r['accessToken'][accessToken][1:]
This will give you the access token "******************", which is everything from index 1 onwards. If you just want the entire string, you can omit the [1:] portion.
The solution was to edit the code provided by yeeshue99, the 2nd value to 'accessToken' with the '' marks. the [1:] was also not needed.
Solution
bearerToken = r['accessToken']['accessToken']
I am new to Gatling and Scala and I need your advice.
I would like to obtain load test for n-users. Each user have to send request for creating different accounts. This is obtained by sending json file with appropriate array of objects ('entries' in our case).
Each single user must send different login as our backend system is checking if username is unique. Somehow we have to be sure that gatling is sending different data for each virtual user and also for each entries as well.
We noticed that there us session element which represents virtual user's state. Problem is that code showed below will not work as Exec structure used with expression function does not send any request.
There is section that could work but I do not know how to determine third parameter to distinguish virtual user id. Please find below simple json file structure used for this test
{
"entries": [
{
"userName": "some user name",
"password": "some password"
}
}
and scala code with my comments
import io.gatling.core.Predef._
import io.gatling.http.Predef._
class UserCreationTest extends Simulation {
val profilesNumber = 2
val virtualUsers = 2
val httpConf = http
.baseURL("some url")
.acceptHeader("application/json")
.basicAuth("username", "password")
// This method will multiply 'entries' section in JSON 'entriesNumber' times
def createJsonUserEntries(entriesNumber: Int, users: List[String], userId : Long): String = {
val header = """{"entries": ["""
val footer = """]}"""
val builder = StringBuilder.newBuilder
for (i <- 0 until entriesNumber) {
val userIndex = (userId.toInt - 1) * entriesNumber + i
val userName = users(userIndex).get
val apiString =
s"""{
"userName": "${userName}"
"password": "password"
}"""
builder.append(apiString)
if (i != entriesNumber) {
builder.append(",")
}
}
header + builder.toString() + footer
}
// We do have method for generating user names based on profilesNumber and virtualUsers variables
// but for sake of this example lets hardcode 4 (profilesNumber * virtualUsers) user names
val usersList = List("user-1", "user-2", "user-3", "user-4")
//This will throw exception as no request was send. According to documentation function block is used to debugging/editing session
val scn = scenario("Create WiFi User Profile")
.exec(session => {
http("CreateUserProfile")
.post("/userProfiles/create/")
.body(StringBody(
createJsonUserEntries(profilesNumber, userslList, session.userId).toString
)
).asJSON
session})
// This exec block will send a request but I do not know how to determine third param that should be virtual user Id
// To run this section please comment previous whole scenario block
/*
val scn = scenario("")
.exec(http("CreateUserProfile")
.post("/userProfiles/create/")
.body(StringBody(
createJsonUserEntries(profilesNumber, emailList, ???).toString
)
).asJSON
)
*/
setUp(scn.inject(atOnceUsers(virtualUsers)).protocols(httpConf))
}
Can you help me on that please? Is there any other way to do that in gatling? Thank you very much in advance
so you are trying to have each user have a unique userId?
you could create a feeder that does this
var userIdFeeder = (1 to 999999).toStream.map(i => Map("userId" -> i)).toIterator
val scn = scenario("")
.feed(userIdFeeder)
.exec(http("CreateUserProfile")
.post("/userProfiles/create/")
.body(StringBody(
createJsonUserEntries(profilesNumber, emailList, "${userId}").toString
)
).asJSON
)
I'm using node forge (https://www.npmjs.com/package/node-forge) to create a public and private key pair (nodeforge.pki.rsa.generateKeyPair()) for testing purposes. The modulo (n) and exponent (e) of the public key is represented as an array of decimal values. However, the service that will provide the public key for encryption in production represents modulo and exponent in hex values. My question now is, how can I easily transform these values created by node forge from decimal to hex (I then want to use these values in NodeRSA (https://github.com/rzcoder/node-rsa)):
let pair = nodeforge.pki.rsa.generateKeyPair();
var key = new NodeRSA();
key.importKey({
n: new Buffer(pair.publicKey.n.data, 'hex'),
e: new Buffer(pair.publicKey.e.data, 'hex')
});
The format of the public key provided by node forge is:
"publicKey": {
"n": {
"data": [
95452259,
62292680,
234781115,
46168802,
112578909,
58538647,
44874864,
186853653,
197342112,
104676488,
229032986,
262511790,
101189381,
134141598,
55892282,
145717908,
78729040,
107967002,
62922480,
120440374,
262852613,
65361518,
128040269,
29796715,
171859902,
201093939,
131227011,
165441987,
9273795,
130804401,
240125365,
221986724,
32034899,
180589760,
106981089,
188935555,
21820073,
96309166,
54553752,
100808208,
198611546,
11382488,
139519439,
212193674,
26780810,
225883560,
101310123,
78467199,
181998612,
8435669,
195696345,
41284550,
129888967,
137003722,
74415901,
92893643,
57787310,
143216416,
42433969,
100838107,
34667532,
136300465,
185624737,
67347,
93800454,
226047286,
76852009,
57120535,
266741908,
27775411,
39685199,
4113773,
214629603,
12
],
"t": 74,
"s": 0
},
"e": {
"data": [
65537
],
"t": 1,
"s": 0
}
The reason I want to do that is that I want to test if the encryption facility works correctly (first, encrypt a value with the public key, then decrypt the value with the private key again), because the public key is provided by an external party and else I have no possibility to check, as the private key is not provided.
Thanks a lot in advance!
You can use toString(16) to convert to hexadecimal
var nHex = publicKey.n.toString(16);
var eHex = publicKey.e.toString(16);
What exactly does the response from https://www.googleapis.com/oauth2/v3/certs mean? I am trying to verify a JWT I got via the Google OpenID Connect process using node-jsonwebtokens and the key used to verify the signature must be one of those two. The source code however suggests that node-jsonwebtokens awaits a different key format than available in the response:
[
{
'kty': 'RSA',
'alg': 'RS256',
'use': 'sig',
'kid': 'e53139984bd36d2c230552441608cc0b5179487a',
'n': 'w5F_3au2fyRLapW4K1g0zT6hjF-co8hjHJWniH3aBOKP45xuSRYXnPrpBHkXM6jFkVHs2pCFAOg6o0tl65iRCcf3hOAI6VOIXjMCJqxNap0-j_lJ6Bc6TBKgX3XD96iEI92iaxn_UIVZ_SpPrbPVyRmH0P7B6oDkwFpApviJRtQzv1F6uyh9W_sNnEZrCZDcs5lL5Xa_44-EkhVNz8yGZmAz9d04htNU7xElmXKs8fRdospyv380WeaWFoNJpc-3ojgRus26jvPy8Oc-d4M5yqs9mI72-1G0zbGVFI_PfxZRL8YdFAIZLg44zGzL2M7pFmagJ7Aj46LUb3p_n9V1NQ',
'e': 'AQAB'
},
{
'kty': 'RSA',
'alg': 'RS256',
'use': 'sig',
'kid': 'bc8a31927af20860418f6b2231bbfd7ebcc04665',
'n': 'ucGr4fFCJYGVUwHYWAtBNclebyhMjALOTUmmAXdMrCIOgT8TxBEn5oXCrszWX7RoC37nFqc1GlMorfII19qMwHdC_iskju3Rh-AuHr29zkDpYIuh4lRW0xJ0Xyo2Iw4PlV9qgqPJLfkmE5V-sr5RxZNe0T1jyYaOGIJ5nF3WbDkgYW4GNHXhv-5tOwWLThJRtH_n6wtYqsBwqAdVX-EVbkyZvYeOzbiNiop7bDM5Td6ER1oCBC4NZjvjdmnOh8-_x6vB449jL5IRAOIIv8NW9dLtQd2DescZOw46HZjWO-zwyhjQeYY87R93yM9yivJdfrjQxydgEs8Ckh03NDATmQ',
'e': 'AQAB'
}
]
It doesn't have the classical BEGIN PUBLIC KEY block, is it maybe encoded? Is there an additional step needed?
That code indeed deals with PEM-formatted certificates/keys instead of the JSON Web Key (JWK) formatted key material that is published by Google on the URL that you gave.
There is however a different URL that serves the (same) key material in PEM format here: https://www.googleapis.com/oauth2/v1/certs. You can use that representation in node-jsonwebtoken.
I was able to use n and e successfully with the following code, and then create a public key in Java to decode a JWT which was sent by Google.
String n_str = "...string value of n.... ";
String e_str = "... string value of e...";
byte[] n_bytes = Base64.getUrlDecoder().decode(n_str);
byte[] e_bytes = Base64.getUrlDecoder().decode(e_str);
BigInteger n = new BigInteger(1, n_bytes);
BigInteger e = new BigInteger(1, e_bytes);
RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(n,e);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);