feat: link local library
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
from cryptojwt.jwk.jwk import key_from_jwk_dict
|
||||
from cryptojwt.jwk.rsa import new_rsa_key
|
||||
from cryptojwt.jwk.ec import new_ec_key
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from cryptojwt.jwk.rsa import RSAKey
|
||||
from cryptojwt.jwk.ec import ECKey
|
||||
from cryptography.hazmat.primitives.asymmetric import rsa, ec
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
from . import settings as local_settings
|
||||
|
||||
|
||||
DEFAULT_HASH_FUNC = getattr(
|
||||
settings, "DEFAULT_HASH_FUNC", local_settings.DEFAULT_HASH_FUNC
|
||||
)
|
||||
|
||||
|
||||
def create_jwk(key=None, hash_func=None, typ: str = getattr(settings, "PRIVATE_KEY_TYPE", None)):
|
||||
if key:
|
||||
key = key
|
||||
elif typ and typ.lower() == 'ec':
|
||||
key = new_ec_key(crv="P-256")
|
||||
else:
|
||||
key = new_rsa_key()
|
||||
|
||||
thumbprint = key.thumbprint(hash_function=hash_func or DEFAULT_HASH_FUNC)
|
||||
jwk = key.to_dict()
|
||||
jwk["kid"] = thumbprint.decode()
|
||||
return jwk
|
||||
|
||||
|
||||
def public_jwk_from_private_jwk(jwk_dict: dict):
|
||||
# exports public
|
||||
_k = key_from_jwk_dict(jwk_dict)
|
||||
jwk = _k.serialize()
|
||||
jwk["kid"] = jwk_dict['kid']
|
||||
return jwk
|
||||
|
||||
|
||||
def private_pem_from_jwk(jwk_dict: dict):
|
||||
# exports private
|
||||
|
||||
_k = key_from_jwk_dict(jwk_dict)
|
||||
pk = _k.private_key()
|
||||
pem = pk.private_bytes(
|
||||
encoding=serialization.Encoding.PEM,
|
||||
format=serialization.PrivateFormat.TraditionalOpenSSL,
|
||||
encryption_algorithm=serialization.NoEncryption(),
|
||||
)
|
||||
return pem.decode()
|
||||
|
||||
|
||||
def public_pem_from_jwk(jwk_dict: dict):
|
||||
# exports private
|
||||
|
||||
_k = key_from_jwk_dict(jwk_dict)
|
||||
pk = _k.public_key()
|
||||
cert = pk.public_bytes(
|
||||
encoding=serialization.Encoding.PEM,
|
||||
format=serialization.PublicFormat.SubjectPublicKeyInfo,
|
||||
)
|
||||
return cert.decode()
|
||||
|
||||
|
||||
def serialize_key(key, kind="public", hash_func="SHA-256"):
|
||||
"""
|
||||
key can be:
|
||||
- cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey
|
||||
- cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey
|
||||
- cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey
|
||||
- cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey
|
||||
- str or bytes (PEM format)
|
||||
"""
|
||||
data = {}
|
||||
|
||||
# Handle RSA keys
|
||||
if isinstance(key, rsa.RSAPublicKey):
|
||||
data = {"pub_key": key}
|
||||
elif isinstance(key, rsa.RSAPrivateKey):
|
||||
data = {"priv_key": key}
|
||||
# Handle EC keys
|
||||
elif isinstance(key, ec.EllipticCurvePublicKey):
|
||||
data = {"pub_key": key}
|
||||
elif isinstance(key, ec.EllipticCurvePrivateKey):
|
||||
data = {"priv_key": key}
|
||||
# Handle PEM strings/bytes
|
||||
elif isinstance(key, (str, bytes)):
|
||||
if kind == "private":
|
||||
if isinstance(key, rsa.RSAPrivateKey) or (isinstance(key, str) and "RSA" in key):
|
||||
data = {"priv_key": private_jwk_from_pem(key)}
|
||||
else:
|
||||
data = {"priv_key": private_jwk_from_pem(key)}
|
||||
else:
|
||||
if isinstance(key, rsa.RSAPublicKey) or (isinstance(key, str) and "RSA" in key):
|
||||
data = {"pub_key": public_jwk_from_pem(key)}
|
||||
else:
|
||||
data = {"pub_key": public_jwk_from_pem(key)}
|
||||
|
||||
# Create appropriate JWK object based on key type
|
||||
if isinstance(key, (rsa.RSAPublicKey, rsa.RSAPrivateKey)) or (isinstance(key, str) and "RSA" in key):
|
||||
jwk_obj = RSAKey(**data)
|
||||
else:
|
||||
jwk_obj = ECKey(**data)
|
||||
|
||||
thumbprint = jwk_obj.thumbprint(hash_function=hash_func)
|
||||
jwk = jwk_obj.to_dict()
|
||||
jwk["kid"] = thumbprint.hex() # Use hex() instead of decode()
|
||||
return jwk
|
||||
|
||||
|
||||
def private_jwk_from_pem(content:str, password:str = None):
|
||||
content = content.encode() if isinstance(content, str) else content
|
||||
key = serialization.load_pem_private_key(content, password=password)
|
||||
return serialize_key(key, kind='private')
|
||||
|
||||
|
||||
def public_jwk_from_pem(content:str, password:str = None):
|
||||
content = content.encode() if isinstance(content, str) else content
|
||||
key = serialization.load_pem_public_key(content)
|
||||
return serialize_key(key, kind='public')
|
||||
Reference in New Issue
Block a user