Validate an Azure idToken in Node.js - node.js

I am having trouble validating the token signature of an Azure idtoken issued by the v2 endpoint.
I have read the documentation (https://learn.microsoft.com/en-us/azure/active-directory/develop/v1-id-and-access-tokens#validating-tokens), and there is also some sample code, but this refers to a languaage other than TS/JS.
Currently I my code is
import {
decode,
verify
} from 'jsonwebtoken';
const token = 'myRand0mIdtoken...meh';
const key = 'key from -->'; // https://login.microsoftonline.com/common/discovery/v2.0/keys
console.log(
decode(token), //works fine!
verify(token, key) //JsonWebTokenError: invalid algorithm
);
How would I go about this? Decoding works, but verifying does not.
The site https://login.microsoftonline.com/common/discovery/v2.0/keys points to a JSON document containing a "keys" array. This contains multiple key objects. Of this, i have used the element in which the "kid" value matches the "kid" value in my idToken's header.
In this element there are two fields, x5t and x5c, which look like public keys. I have tried both, but no luck.
Kind regards

Found the solution.
https://nicksnettravels.builttoroam.com/post/2017/01/24/Verifying-Azure-Active-Directory-JWT-Tokens.aspx
It seems, that I have just forgotten the starting and ending lines encompassing the public key. The working format is:
-----BEGIN CERTIFICATE-----
CONTENT OF x5c FIELD IN THE JSON DOC
-----END CERTIFICATE-----

Related

Performing ECIES operation using Bouncy castle with KeyPair in JKS

I have requirement to perform ECIES encryt/decrypt using secp256r1 with BC as provider.
I have need reference of (1) how to store ECIES private-public key pair in JKS Keystore (2) retrieve public key from JKS.
I have provision key-pair using keytool command as per https://zombiesecured.com/html/tutorials/Keytool/ECC-JK.html.
Signature algorithm name: SHA256withECDSA
Subject Public Key Algorithm: 256-bit EC key
(2) Can you help how to retrieve key in ECDSAPublicKey format as input to encryption .
I have found reference of decoding key to ECPublicKey as below. What should be my 1st argument? How to retrieve encoded key from JKS?
public static ECPublicKey decodePublicKey(byte[] encoded, String namedCurve) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchProviderException, IOException
{
KeyFactory fact = KeyFactory.getInstance("ECDSA", BouncyCastleProvider.PROVIDER_NAME);
ECNamedCurveParameterSpec params = ECNamedCurveTable.getParameterSpec(namedCurve);
java.security.spec.EllipticCurve ellipticCurve = EC5Util.convertCurve(params.getCurve(), params.getSeed());
java.security.spec.ECPublicKeySpec keySpec = new java.security.spec.ECPublicKeySpec(ECPointUtil.decodePoint(ellipticCurve,encoded),EC5Util.convertSpec(ellipticCurve, params));
return (ECPublicKey) fact.generatePublic(keySpec);
}
how to use IESCipher, IESParameterSpec, engineInit to perform ECIES encrypt/decrypt.

HMAC SHA256 Produces Different Result if String vs Variable in Liquid, Shopify

I'm doing some URL verification between a Shopify site and my app. On Shopify, in a .liquid file, I'm creating an HMAC value using Shopify's built in hmac_sha256 string filter. I'm using a secret key and a Twitch user ID which I've stored in a customer tag.
The hash value is passed as a query parameter to my app, which uses the crypto module in node.js to generate a hash and compare it with the hash from the url.
Things get strange here: In the .liquid file, when I type the Twitch ID directly into the string filter, the hash value generated by the .liquid file is the same value my app generates, and everything looks good:
{{ "12345678" | hmac_sha256: "secret_key" }}
However, when I pass the same Twitch ID as a variable into the string filter, the hash value the liquid file generates is different than the first time:
{{ twitchId | hmac_sha256: "secret_key" }}
I've already tried removing whitespace and newline characters from the Twitch ID variable just in case there were any. I don't even have a guess as to what the problem could be. Maybe the variable (which is a string) is encoded differently than when I type it in directly?
For reference, the javascript code checking for matching hashes:
// Get query string params:
const { hash, twitchId } = req.query;
console.log('Twitch ID in query: ' + twitchId);
// Verify user
const generatedUserHash = crypto
.createHmac('sha256', userVerifySecret)
.update(twitchId)
.digest('hex');
console.log('Passed hash: ' + hash + ' Generated hash: ' + generatedUserHash);
if (generatedUserHash == hash) {
return true;
} else {
return false;
}
You need to show how you are assigning the ID to the variable. Without seeing that, there is no way to validate your question.
I did a quick test, and proved I get the same HMAC with a string and a variable, so it must be that you are doing something weird in your assignment:
<h1>{{ "12345678" | hmac_sha256: "secret_key" }}</h1>
{% capture fizz %}12345678{% endcapture%}
<h1>{{ fizz | hmac_sha256: "secret_key"}}</h1>
Produces:
fcfebc0d424982ce8c7a986264beb0d4b1de44507501451e142236404e5b9778
fcfebc0d424982ce8c7a986264beb0d4b1de44507501451e142236404e5b9778
Turns out my variable twitchId was getting instantiated after I was trying to use it in the sha256 filter. I was instantiating it in my theme.liquid file, and I was trying to access it in a liquid file in my app (the request from the Shopify site is responded to with a liquid file).
I guess I wrongly assumed the theme.liquid file is loaded before the file in my response to Shopify. I assumed this because javascript variables I instantiate in my theme.liquid file are available in my response liquid file (I think this has something to do with liquid variables being created server-side and javascript variables being created client-side).
I am now instantiating the twitchId variable in my response liquid file. So that solved it.

how to encrypt password text input using script mode in Katalon ?

I have a csv with a list of users and passwords that I need check the login.
Is there any way to encrypt password text input using script mode in
Katalon ?
I found an answer on katalon forums but they do that manually using a a tool of the IDE like you can see here Working with Sensitive Text
I would like to create an script that for every (user,password) encrypt the password and login using encrypted password.
#Keyword
def login(user, password, url){
WebUI.navigateToUrl(url)
WebUI.setText(findTestObject('Object Repository/Page_Sign in My Page/input_SigninFormemail'),user)
def password_encript = Encrypt(password)// Fictitious method that I would like to get
WebUI.setEncryptedText(findTestObject('Object Repository/Page_Sign in My Page/input_SigninFormpassword'), password_encript)
WebUI.click(findTestObject('Object Repository/Page_Sign in My Page/input_yt0'))
}
Is there a method like Encrypt(password) in Katalon?
Is there a way to do that in code?
Thanks in advance.
I came across this question while investigating other Katalon encryption questions, and thought I may offer some late insight.
The "setEncryptedText(TestObject, encryptedText)" method is to allow you to store sensitive text in an encrypted form, which is then decrypted when entered into the web application.
Since your method is being passed 'password' as a string in cleartext, then why not just have the function do:
WebUI.setText(findTestObject('Object Repository/Page_Sign in My Page/input_SigninFormpassword'), password)
So to use Java Encryption : Blowfish with Text and Key.
Here is my solution :
public static String encrypt(String strClearText,String strKey) throws Exception{
String strData="";
// streData - here you put your data
try {
SecretKeySpec skeyspec=new SecretKeySpec(strKey.getBytes(),"Blowfish");
Cipher cipher=Cipher.getInstance("Blowfish");
cipher.init(Cipher.ENCRYPT_MODE, skeyspec);
byte[] encrypted=cipher.doFinal(strClearText.getBytes());
strData=new String(encrypted);
} catch (Exception e) {
e.printStackTrace();
throw new Exception(e);
}
return strData;
}

How to call a contract function from a specific address

I want to use web3 to call a contract function(sendTransaction not call) from a specific address that I hold the private key to. I also have the contract instance connected. I know I have to dio something like web3.personal.unlockAccount(address,password,duration)
And then specify the from address.
So my question is, is "password" where I enter my private key? And how do I pass that address into fromAddress once I unlock it.
Or is there a more streamlined way to go about it?
is "password" where I enter my private key?
No, it's not. Actually it is a password, which you entered when you were creating account and which was used to generate your keystore file.
If you use web3.personal.unlockAccount(address,password,duration) you need to have your keystore file in the keystore folder near chaindata of geth.
Another way will be to use web3.eth.sendRawTransaction from web3.py, but it will be a little bit clunky to call contract method from it.
key = '0x' + 'YOUR-PRIVATE-KEY
transaction = {
'to': _to,
'value': 0,
'gas': 300000,
'gasPrice': 23000000000,
'nonce': web3.eth.getTransactionCount(_from),
'chainId': int(web3.admin.nodeInfo['protocols']['eth']['network']),
'data': b''
}
signed = web3.eth.account.signTransaction(transaction, key)
print("Transaction Hash: " + web3.toHex(web3.eth.sendRawTransaction(signed.rawTransaction)))
My suggestion will be to create keyfile recognisable by Ethereum clients by using web3.eth.account.encrypt (web3.py because web3.js yet lack this functionality) and after you generate it put it in the right folder and try simply to unlock account.

List of keys that should most probably be removed from log files?

Recently I noticed some sensitive data was being written out to a log file in an app I'm working on. I looked into it, and our app has a list of keys that it will remove from our logs before writing them out, but the list feels to me like it could be expanded.
Is there a list somewhere of common keys that should be removed from log files when found?
For example the following keys and their variations should probably never be logged anywhere in a log file
access_token
auth_token
client_id
client_secret
oauthSecret
oauthToken
password
refresh_token
connection_string
Note that I've seen the OWASP Logging cheat sheet, but it didn't seem to have any specifics in it, just generalizations.
So far the best I've been able to come up with is the following, and I found my best results by searching for "redact secret password token" in Google.
Redact keys that have the following anywhere in their name
remembering that keys can show up in any of the following ways: x=y, x:y, 'x':y, "x":y <x>y</x>
token
secret
password
session
connection
jwt
consider removing all username variations as well, like:
username
user_name
user
email
credential
Redact values that look like
credit card numbers
social insurance numbers
possibly email addresses
Cloudera has a page detailing regular expressions for redacting some data values, not keys:
Credit Card numbers (with separator)
\d{4}[^\w]\d{4}[^\w]\d{4}[^\w]\d{4}
Social Security numbers (with separator) \d{3}[^\w]\d{2}[^\w]\d{4}
Email addresses \b([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-._] \
[A-Za-z0-9])#(([A-Za-z0-9]|[A-Za-z] \ [A-Za-z0-9-][A-Za-z0-9]).)+([A-Za-z0-9] \
|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9])\b
Hostnames \b(([A-Za-z]|[A-Za-z][A-Za-z0-9-] \
[A-Za-z0-9]).)+([A-Za-z0-9] \ |[A-Za-z0-9][A-Za-z0-9-][A-Za-z0-9])\b
Node module for redacting data
https://github.com/watson/redact-secrets
Note: A coworker of mine did a great job of supplying me with a java sample of key value redacting in Java, using a regex to eliminate key values that contain `session,secret,token,password,passwd,connection' in xml and json, and quoted variants.
import java.security.GeneralSecurityException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Redact {
private static final String prefix = "[\"']?(session|(auth_)?token|password|passwd|secret|connection)[\"']?";
private static final String capture = "([\"']?)([\\w\\d!#$%()*+,-./:<=>?#[\\\\]^_`{|}~]+)([\"']?)";
private static Pattern pattern = Pattern.compile(prefix + "\\s*(=|:)\\s*" + capture, Pattern.CASE_INSENSITIVE);
public static String encryptSensitiveInfo(String message) {
try {
if (message == null)
return message;
StringBuffer newStr = new StringBuffer(message);
int lenDiff = 0;
Matcher m = pattern.matcher(message);
// Loop over message until all sensitive data is redacted
while (m.find()) {
String keyAndValue = m.group(0);
String value = m.group(5);
String REDACTED = "REDACTED";
String replacementText = keyAndValue.replace(value, REDACTED);
// Replace the key/value in the message with the new redacted
// value, adjusting for where it is in the redacted version of
// the input
newStr = newStr.replace(m.start() - lenDiff, m.end() - lenDiff, replacementText);
lenDiff += keyAndValue.length() - replacementText.length();
}
return newStr.toString();
} catch (Exception e) {
return message;
}
}
}

Resources