From a44cd5a074861337066a67c571add1f611c1c134 Mon Sep 17 00:00:00 2001 From: Hsiaoming Yang Date: Thu, 27 Feb 2025 18:18:20 +0900 Subject: [PATCH] fix: use secrets module to generate random bytes --- README.md | 3 +-- src/joserfc/rfc7516/models.py | 6 +++--- src/joserfc/rfc7518/jwe_algs.py | 6 +++--- src/joserfc/rfc7518/oct_key.py | 5 ++--- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index ad731cc..342f20c 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,9 @@ `joserfc` is a Python library that provides a comprehensive implementation of several essential JSON Object Signing and Encryption (JOSE) standards. -[![GitHub Sponsor](https://badgen.net/badge/support/joserfc/blue?icon=github)](https://github.com/sponsors/lepture) [![Build Status](https://github.com/authlib/joserfc/actions/workflows/test.yml/badge.svg)](https://github.com/authlib/joserfc/actions) [![PyPI Version](https://badgen.net/pypi/v/joserfc)](https://pypi.org/project/joserfc) -[![PyPI Downloads](https://static.pepy.tech/personalized-badge/joserfc?period=month&units=international_system&left_color=black&right_color=brightgreen&left_text=downloads/month)](https://pepy.tech/projects/joserfc) +[![PyPI Downloads](https://badgen.net/pypi/dm/joserfc)](https://pepy.tech/projects/joserfc) [![Code Coverage](https://codecov.io/gh/authlib/joserfc/branch/main/graph/badge.svg?token=WCD9X8HKI1)](https://codecov.io/gh/authlib/joserfc) [![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=authlib_joserfc&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=authlib_joserfc) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=authlib_joserfc&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=authlib_joserfc) diff --git a/src/joserfc/rfc7516/models.py b/src/joserfc/rfc7516/models.py index ed44962..062cdc8 100644 --- a/src/joserfc/rfc7516/models.py +++ b/src/joserfc/rfc7516/models.py @@ -1,6 +1,6 @@ from __future__ import annotations -import os import typing as t +import secrets from abc import ABCMeta, abstractmethod from ..registry import Header, HeaderRegistryDict from ..errors import InvalidKeyTypeError, InvalidKeyLengthError @@ -168,10 +168,10 @@ class JWEEncModel(object, metaclass=ABCMeta): cek_size: int def generate_cek(self) -> bytes: - return os.urandom(self.cek_size // 8) + return secrets.token_bytes(self.cek_size // 8) def generate_iv(self) -> bytes: - return os.urandom(self.iv_size // 8) + return secrets.token_bytes(self.iv_size // 8) def check_iv(self, iv: bytes) -> bytes: if len(iv) * 8 != self.iv_size: # pragma: no cover diff --git a/src/joserfc/rfc7518/jwe_algs.py b/src/joserfc/rfc7518/jwe_algs.py index 79b8e82..9838a8f 100644 --- a/src/joserfc/rfc7518/jwe_algs.py +++ b/src/joserfc/rfc7518/jwe_algs.py @@ -1,5 +1,5 @@ from __future__ import annotations -from os import urandom +import secrets from cryptography.hazmat.primitives.asymmetric import padding from cryptography.hazmat.primitives import hashes from cryptography.hazmat.backends import default_backend @@ -151,7 +151,7 @@ def encrypt_cek(self, cek: bytes, recipient: Recipient[OctKey]) -> bytes: #: The "iv" (initialization vector) Header Parameter value is the #: base64url-encoded representation of the 96-bit IV value iv_size = 96 - iv = urandom(iv_size // 8) + iv = secrets.token_bytes(iv_size // 8) cipher = Cipher(AES(op_key), GCM(iv), backend=default_backend()) enc = cipher.encryptor() @@ -264,7 +264,7 @@ def compute_derived_key(self, key: bytes, p2s: bytes, p2c: int) -> bytes: def encrypt_cek(self, cek: bytes, recipient: Recipient[OctKey]) -> bytes: headers = recipient.headers() if "p2s" not in headers: - p2s = urandom(16) + p2s = secrets.token_bytes(16) recipient.add_header("p2s", urlsafe_b64encode(p2s).decode("ascii")) else: p2s = urlsafe_b64decode(to_bytes(headers["p2s"])) diff --git a/src/joserfc/rfc7518/oct_key.py b/src/joserfc/rfc7518/oct_key.py index 875a912..7978b1a 100644 --- a/src/joserfc/rfc7518/oct_key.py +++ b/src/joserfc/rfc7518/oct_key.py @@ -1,6 +1,6 @@ from __future__ import annotations from typing import Any -from os import urandom +import secrets from ..util import ( to_bytes, urlsafe_b64decode, @@ -68,8 +68,7 @@ def generate_key( if key_size % 8 != 0: raise ValueError("Invalid bit size for oct key") - value = urandom(key_size // 8) - raw_key = to_bytes(value) + raw_key = secrets.token_bytes(key_size // 8) key: OctKey = cls(raw_key, raw_key, parameters) if auto_kid: key.ensure_kid()