简体   繁体   English

是否可以使用 Azure Key Vault 的密钥 ZDB94644238D108ADE18

[英]Is it possible to create a JSON Web Token using Azure Key Vault's Keys API?

I am currently using the jsonwebtokens package for generating signed JWTs with a RSA signing key.我目前正在使用jsonwebtokens package 生成带有 RSA 签名密钥的签名 JWT。 I was experimenting to see how I can move to Azure Key Vault .我正在尝试查看如何迁移到Azure Key Vault One way I can do is to store the private and public keys as Vault Secrets.我可以做的一种方法是将私钥和公钥存储为 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.但我注意到还有一个 Vault Keys API 在 Vault 中生成一个密钥并签署我提供的数据。

I've been trying with the @azure/keyvault-keys package and this is where I've got:我一直在尝试使用@azure/keyvault-keys package,这就是我得到的地方:

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.生成的签名签名看起来与我通常使用jsonwebtoken package 得到的签名完全不同。 My intention is that I'd like to sign my tokens with Vault but would like to verify with jsonwebtoken.verify() .我的意图是我想用 Vault 签署我的令牌,但想用jsonwebtoken.verify()进行验证。 Is this even possible?这甚至可能吗? What am I doing wrong in my code?我在我的代码中做错了什么?

Since you use the Azure kay vault to sign jwt, we also can use Azure key vault to Verify the jwt由于您使用 Azure kay vault 签署 jwt,我们也可以使用 Azure key vault 来验证 jwt。

For example例如

 const key = await this.keyClient.getKey(this.KEY_NAME);
 const cryptClient = new CryptographyClient(key, new DefaultAzureCredential());
const util =require('util')
const base64 = require('base64url');
const JWT=""
    const jwtHeader = JWT.split('.')[0];
    const jwtPayload = JWT.split('.')[1];
    const jwtSignature = JWT.split('.')[2];
    const signature = base64.toBuffer(jwtSignature)
    const data = util.format('%s.%s', jwtHeader, jwtPayload);
    const hash = crypto.createHash('sha256');
    const digest = hash.update(data).digest()
const verified =await cryptClient.verify("RS256",digest,signature)

Besides If you want to use jsonwebtoken package to verify jet, please refer to the following code另外如果要使用jsonwebtoken package来验证jet,请参考以下代码

const util =require('util')
const base64 = require('base64url');
const forge = require('node-forge');
const jwt = require('jsonwebtoken')
async Function test{
// gerenrate jwt
const headerObj = {
        alg: 'RS256',
        typ: 'JWT'
    };
    
    const payloadObj = {
        sub: '1234567890',
        name: 'John Doe'
       
    };
    
    const encodedHeader = base64(JSON.stringify(headerObj));
    const encodedPayload = base64(JSON.stringify(payloadObj));
    const data = util.format('%s.%s', encodedHeader, encodedPayload);

    const hash = crypto.createHash('sha256');
    const digest = hash.update(data).digest()
   
    
    const keyClient =new KeyClient("https://testsql.vault.azure.net/",new DefaultAzureCredential());
    const key =await keyClient.getKey("test");
    const cryptClient = new CryptographyClient(key.id, new DefaultAzureCredential());
    const signResult = await cryptClient.sign("RS256",digest)     
    const jwts =util.format('%s.%s.%s', encodedHeader, encodedPayload,base64(signResult.result));
    console.log(jwts)

// verify

// convert azure key vault ket to public key
var n =Buffer.from(key.key.n).toString("base64")   
    var e =Buffer.from(key.key.e).toString("base64")
    var publicKey = forge.pki.setRsaPublicKey(
        base64urlToBigInteger(n),
        base64urlToBigInteger(e)); 
// convert public key to pem file
     var pem = forge.pki.publicKeyToPem(publicKey);
    var d= jwt.decode(jwts,pem.toString())
    console.log(d)
}




function base64urlToBigInteger(str) {
   
    var bytes = forge.util.decode64(
      (str + '==='.slice((str.length + 3) % 4))
        .replace(/\-/g, '+')
        .replace(/_/g, '/'));
    return new forge.jsbn.BigInteger(forge.util.bytesToHex(bytes), 16);
  };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM