I am currently using the jsonwebtokens
package for generating signed JWTs with a RSA signing key. I was experimenting to see how I can move to Azure Key Vault. One way I can do is to store the private and public keys as Vault Secrets. But I noticed that there's also a Vault Keys API which generates a key in Vault and signs data which I provide it.
I've been trying with the @azure/keyvault-keys
package and this is where I've got:
async signJsonWebToken(data: object, expiry: string): Promise<string> {
const headerB64 = this.base64url(JSON.stringify(this.keyHeader), 'binary');
const payloadB64 = this.base64url(this.getTokenData(data, expiry), 'utf8');
const payload = `${headerB64}.${payloadB64}`;
const key = await this.keyClient.getKey(this.KEY_NAME);
const cryptClient = new CryptographyClient(key, new DefaultAzureCredential());
const hash = crypto.createHash('sha256');
const digest = hash.update(payload).digest();
const signResult = await cryptClient.sign('RS256', digest);
const signResultB64 = this.base64url(signResult.result.toString(), 'utf8');
const result = `${payload}.${signResultB64}`;
this.logger.log('Key: ' + key.key);
this.logger.log('Sign result: ' + result);
return result;
}
private base64url(data: string, encoding: string) {
return SBuffer
.from(data, encoding)
.toString('base64')
.replace(/=/g, '')
.replace(/\+/g, '-')
.replace(/\//g, '_');
}
private getTokenData(data: object, expiry: string): string {
const now = Date.now();
const expiresIn = new Date();
if (expiry.endsWith('d')) {
expiresIn.setDate(expiresIn.getDate() + parseInt(expiry));
} else if (expiry.endsWith('h')) {
expiresIn.setHours(expiresIn.getHours() + parseInt(expiry));
} else if (expiry.endsWith('m')) {
expiresIn.setMinutes(expiresIn.getMinutes() + parseInt(expiry));
}
const tokenData = Object.assign({
iat: now,
exp: expiresIn.getTime()
}, data);
return JSON.stringify(tokenData);
}
The generated signed signature do not look anywhere close to what I'd usually be getting with the jsonwebtoken
package. My intention is that I'd like to sign my tokens with Vault but would like to verify with jsonwebtoken.verify()
. Is this even possible? What am I doing wrong in my code?