How can I sign a JWT with RS256 using PS256 private key #637
-
Hello, openssl req -newkey rsa-pss -new -nodes -x509 -days 3650 -pkeyopt rsa_keygen_bits:4096 -sigopt rsa_pss_saltlen:32 -keyout key.pem -out cert.pem
openssl x509 -pubkey -noout -in cert.pem > pubkey.pem I have thoe following working Java code: private static String createJwtToken() {
try {
Path privateKeyPath = Path.of("/Users/abc/bzstcerts/key.pem");
Path publicKeyPath = Path.of("/Users/abc/bzstcerts/pubkey.pem");
RSAPrivateKey privateKey = (RSAPrivateKey)readPrivateKey(privateKeyPath);
RSAPublicKey publicKey =(RSAPublicKey) readPublicKey(publicKeyPath);
Algorithm algorithm = Algorithm.RSA256( publicKey, privateKey);
return JWT.create()
.withIssuer("iss")
.withSubject("subject")
.withAudience("audience")
.withIssuedAt(new Date())
.withExpiresAt(new Date(System.currentTimeMillis() + (5 * 60 * 1000L)))
.withJWTId(UUID.randomUUID().toString())
.withNotBefore(new Date(System.currentTimeMillis() - 60 * 1000L))
.sign(algorithm);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private static PrivateKey readPrivateKey(Path privateKeyPath) throws Exception {
byte[] keyBytes = Files.readAllBytes(privateKeyPath);
keyBytes = Base64.getDecoder().decode(keyBytes);
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSASSA-PSS");
return keyFactory.generatePrivate(spec);
}
private static PublicKey readPublicKey(Path publicKeyPath) throws Exception {
byte[] keyBytes = Files.readAllBytes(publicKeyPath);
keyBytes = Base64.getDecoder().decode(keyBytes);
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSASSA-PSS");
return keyFactory.generatePublic(spec);
} Here the private and public keys are loaded using RSASSA-PSS and casted to RSAPrivateKey and RSAPublicKey respectively. I try to achieve the same with jose in node but I have no success. import * as fs from 'fs'
import * as jose from 'jose'
import * as uuid from 'uuid'
import path from 'node:path'
const jwtUuid = uuid.v4()
const currentTime = Math.floor(Date.now() / 1000)
const expirationTime = currentTime + 300
const notValidBeforeTime = currentTime - 60
const clientId = process.env.CLIENT_ID
const audienceUrl = process.env.AUDIENCE_URL
const getSignedJWTToken = async () => {
const signOptions: jose.JWTPayload = {
iss: clientId,
sub: clientId,
aud: audienceUrl,
iat: currentTime,
exp: expirationTime,
jti: jwtUuid,
nbf: notValidBeforeTime,
}
const privateKey = await getPrivateKey()
const signedJwt = await new jose.SignJWT(signOptions)
.setProtectedHeader({ alg: 'PS256' })
.setIssuer(clientId)
.setSubject(clientId)
.setAudience(audienceUrl)
.setIssuedAt(currentTime)
.setExpirationTime(expirationTime)
.setJti(jwtUuid)
.setNotBefore(notValidBeforeTime)
.sign(privateKey)
console.log(`\nsignedJwt in generateRequestToken:\n${signedJwt}`)
return signedJwt
}
const certPath = path.resolve('./assets/cert')
const privateKeyName = 'key.pem'
const getPrivateKey = async () => {
const privateKeyPath = `${certPath}/${privateKeyName}`
const privateKeyString = fs.readFileSync(privateKeyPath, 'utf-8')
return await jose.importPKCS8(privateKeyString, 'PS256')
}
const publicKeyName = 'pubkey.pem'
const getPublicKey = async () => {
const publicKeyPath = `${certPath}/${publicKeyName}`
const publicKeyString = fs.readFileSync(publicKeyPath, 'utf-8')
console.log(`\npublicKeyString from readFileSync:\n${publicKeyString}`)
return await jose.importSPKI(publicKeyString, 'PS256')
} I can load the keys and sign the jwt using PS256 algorithm, but I can't load the keys with PS256 algorithm, convert them to RS256 algorithm and sign the jwt. How can I achieve this? Thanks a lot for your help in advance! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
You've generated an RSASSA-PSS key, it cannot be used for RS256, at least not in Node.js, there's no manipulation in the crypto module you could do to drop/change the key's parameters. If you want a key that's usable for both RS256 and PS256 use this -openssl req -newkey rsa-pss -new -nodes -x509 -days 3650 -pkeyopt rsa_keygen_bits:4096 -sigopt rsa_pss_saltlen:32 -keyout key.pem -out cert.pem
+openssl req -newkey rsa -new -nodes -x509 -days 3650 -pkeyopt rsa_keygen_bits:4096 -keyout key.pem -out cert.pem
openssl x509 -pubkey -noout -in cert.pem > pubkey.pem |
Beta Was this translation helpful? Give feedback.
You've generated an RSASSA-PSS key, it cannot be used for RS256, at least not in Node.js, there's no manipulation in the crypto module you could do to drop/change the key's parameters.
If you want a key that's usable for both RS256 and PS256 use this
-openssl req -newkey rsa-pss -new -nodes -x509 -days 3650 -pkeyopt rsa_keygen_bits:4096 -sigopt rsa_p…