6

How to create a JWKS public/private key pair, similar to the one that can be created manually at https://mkjwk.org/, that includes the Key ID (kid) and Key Use (use)? I used the cryptography module for generating a RSA key pair and python-jose for extracting the keys as JWK, but the created keys do not include kid and use (unsurprisingly, as they haven't been specified anywhere).

Code:

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
​
from jose import jwk, constants
import json
​
key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=2048,
    backend=default_backend()
)
public_key = key.public_key().public_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PublicFormat.SubjectPublicKeyInfo
)
private_key = key.private_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PrivateFormat.TraditionalOpenSSL,
    encryption_algorithm=serialization.NoEncryption()
)
​
print(json.dumps(jwk.RSAKey(algorithm=constants.Algorithms.RS256, key=public_key.decode('utf-8')).to_dict()))
print(json.dumps(jwk.RSAKey(algorithm=constants.Algorithms.RS256, key=private_key.decode('utf-8')).to_dict()))

Generated public key by above code snippet (no kid or use properties):

{
    "alg": "RS256",
    "kty": "RSA",
    "n": "tqbcR_6JC....OKQ",
    "e": "AQAB"
}
Anand Jayabalan
  • 12,294
  • 5
  • 41
  • 52

2 Answers2

7

Another way to generate JWKS public/private key pair using the jwcrypto library:

from jwcrypto import jwk

key = jwk.JWK.generate(kty='RSA', size=2048, alg='RSA-OAEP-256', use='enc', kid='12345')
public_key = key.export_public()
private_key = key.export_private()

Generated public key by above snippet:

{
    "kty": "RSA",
    "alg": "RSA-OAEP-256",
    "kid": "12345",
    "use": "enc",
    "e": "AQAB",
    "n": "0YclBn...vV7y7w"
}
Anand Jayabalan
  • 12,294
  • 5
  • 41
  • 52
1

I believe kid is just a piece of metadata (any string) that is not being used in the process of generating the key.

In case of the use it is probably somewhat similar, though depending on the use you want different scheme for asymmetric cryptography (you can refer to the most well-known asymmetric cryptography system of RSA for both encryption and signing schemes' description).

All in all, you can most probably recreate the exact structure of JSON adding appropriate keys to JSON dict based on the information above.

sophros
  • 14,672
  • 11
  • 46
  • 75
  • 2
    *you distribute the Private Key* - then it's not private anymore. Signatures are created with the private key and verified with the public key. – jps May 18 '21 at 16:07
  • So how would you describe e.g. RSA with reference to names from https://en.wikipedia.org/wiki/RSA_(cryptosystem) in application to signatures? Would you use Private Key for the Public Key and vice-versa? How that helps understanding what you mean? – sophros May 18 '21 at 16:21
  • 2
    Not sure what you're asking, but the part about signing is also [explained](https://en.wikipedia.org/wiki/RSA_(cryptosystem)#Signing_messages) in the Wikipedia Article – jps May 18 '21 at 16:24
  • @jps is correct. You sign the data with *your* private key, and everybody else verifies the signature with *your* public key. – President James K. Polk May 18 '21 at 19:04