def _load_keys(self, private_key, private_key_password, public_key): private_key_bytes = strings.to_bytes(private_key) private_key_password_bytes = strings.to_bytes(private_key_password) public_key_bytes = strings.to_bytes(public_key) self.private_key = serialization.load_pem_private_key(data=private_key_bytes, password=private_key_password_bytes, backend=backend) self.public_key = serialization.load_pem_public_key(data=public_key_bytes, backend=backend)
def __init__(self): private_key_bytes = strings.to_bytes(settings.EQ_SUBMISSION_SR_PRIVATE_SIGNING_KEY) public_key_bytes = strings.to_bytes(settings.EQ_SUBMISSION_SDX_PUBLIC_KEY) self.private_key = serialization.load_pem_private_key(private_key_bytes, password=strings.to_bytes(settings.EQ_SUBMISSION_SR_PRIVATE_SIGNING_KEY_PASSWORD), backend=backend) self.public_key = serialization.load_pem_public_key(public_key_bytes, backend=backend) # first generate a random key self.cek = os.urandom(32) # 256 bit random CEK # now generate a random IV self.iv = os.urandom(12) # 96 bit random IV
def _generate_key(user_id, user_ik, pepper): sha256 = hashlib.sha256() sha256.update(to_str(user_id).encode('utf-8')) sha256.update(to_str(user_ik).encode('utf-8')) sha256.update(to_str(pepper).encode('utf-8')) # we only need the first 32 characters for the CEK return to_bytes(sha256.hexdigest()[:32])
def generate_ik(token): logger.debug("About to generate a user ignition key") collection_exercise_sid, eq_id, form_type, ru_ref = UserIDGenerator._get_token_data(token) logger.debug("Using values %s, %s, %s and %s with a salt to generate a user ik", ru_ref, collection_exercise_sid, eq_id, form_type) salt = to_bytes(settings.EQ_SERVER_SIDE_STORAGE_USER_IK_SALT) ik = UserIDGenerator._generate(collection_exercise_sid, eq_id, form_type, ru_ref, salt) if settings.EQ_DEV_MODE: logger.debug("User IK is %s", to_str(ik)) return to_str(ik)
def generate_key(user_id, user_ik, pepper=settings.EQ_SERVER_SIDE_STORAGE_ENCRYPTION_KEY_PEPPER): sha256 = hashlib.sha256() sha256.update(to_str(user_id).encode('utf-8')) sha256.update(to_str(user_ik).encode('utf-8')) sha256.update(to_str(pepper).encode('utf-8')) # we only need the first 32 characters for the CEK cek = sha256.hexdigest()[:32] return to_bytes(cek)
def __init__(self): if settings.EQ_USER_AUTHENTICATION_RRM_PRIVATE_KEY is None: raise Exception("EQ_USER_AUTHENTICATION_RRM_PRIVATE_KEY is None (check EQ_DEV_MODE?)") if settings.EQ_USER_AUTHENTICATION_RRM_PRIVATE_KEY_PASSWORD is None: raise Exception("EQ_USER_AUTHENTICATION_RRM_PRIVATE_KEY_PASSWORD is None (check EQ_DEV_MODE?)") if settings.EQ_USER_AUTHENTICATION_SR_PUBLIC_KEY is None: raise Exception("EQ_USER_AUTHENTICATION_SR_PUBLIC_KEY is None (check EQ_DEV_MODE?)") private_key = strings.to_bytes(settings.EQ_USER_AUTHENTICATION_RRM_PRIVATE_KEY) private_key_password = strings.to_bytes(settings.EQ_USER_AUTHENTICATION_RRM_PRIVATE_KEY_PASSWORD) public_key = strings.to_bytes(settings.EQ_USER_AUTHENTICATION_SR_PUBLIC_KEY) self.private_key = serialization.load_pem_private_key(private_key, password=private_key_password, backend=backend) self.public_key = serialization.load_pem_public_key(public_key, backend=backend) # first generate a random key self.cek = os.urandom(32) # 256 bit random CEK # now generate a random IV self.iv = os.urandom(12) # 96 bit random IV
def _generate(self, key_material, salt): kdf = PBKDF2HMAC( algorithm=hashes.SHA256(), length=32, salt=salt, iterations=self._iterations, backend=backend, ) generated_key = kdf.derive(to_bytes(key_material)) return binascii.hexlify(generated_key)
def _generate(collection_exercise_sid, eq_id, form_type, ru_ref, salt): key_material = ru_ref + collection_exercise_sid + eq_id + form_type kdf = PBKDF2HMAC( algorithm=hashes.SHA256(), length=32, salt=salt, iterations=settings.EQ_SERVER_SIDE_STORAGE_USER_ID_ITERATIONS, backend=backend) generated_key = kdf.derive(to_bytes(key_material)) return binascii.hexlify(generated_key)
def _generate(self, collection_exercise_sid, eq_id, form_type, ru_ref, salt): key_material = ru_ref + collection_exercise_sid + eq_id + form_type kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=salt, iterations=self._iterations, backend=backend) generated_key = kdf.derive(to_bytes(key_material)) return binascii.hexlify(generated_key)
def generate_ik(token): collection_exercise_sid, eq_id, form_type, ru_ref = UserIDGenerator._get_token_data( token) logger.debug("generating user ik", ru_ref=ru_ref, ce_id=collection_exercise_sid, eq_id=eq_id, form_type=form_type) salt = to_bytes(settings.EQ_SERVER_SIDE_STORAGE_USER_IK_SALT) ik = UserIDGenerator._generate(collection_exercise_sid, eq_id, form_type, ru_ref, salt) return to_str(ik)
def _generate_key(user_id: str, user_ik: str, pepper: str) -> jwk.JWK: sha256 = hashlib.sha256() sha256.update(to_str(user_id).encode("utf-8")) sha256.update(to_str(user_ik).encode("utf-8")) sha256.update(to_str(pepper).encode("utf-8")) # we only need the first 32 characters for the CEK cek = to_bytes(sha256.hexdigest()[:32]) password = {"kty": "oct", "k": base64url_encode(cek)} return jwk.JWK(**password)
def generate_ik(token): logger.debug("About to generate a user ignition key") collection_exercise_sid, eq_id, form_type, ru_ref = UserIDGenerator._get_token_data( token) logger.debug( "Using values %s, %s, %s and %s with a salt to generate a user ik", ru_ref, collection_exercise_sid, eq_id, form_type) salt = to_bytes(settings.EQ_SERVER_SIDE_STORAGE_USER_IK_SALT) ik = UserIDGenerator._generate(collection_exercise_sid, eq_id, form_type, ru_ref, salt) if settings.EQ_DEV_MODE: logger.debug("User IK is %s", to_str(ik)) return to_str(ik)
def __init__(self): self.logger = logging.getLogger(__name__) if settings.EQ_USER_AUTHENTICATION_RRM_PUBLIC_KEY is None or settings.EQ_USER_AUTHENTICATION_SR_PRIVATE_KEY is None \ or settings.EQ_USER_AUTHENTICATION_SR_PRIVATE_KEY_PASSWORD is None: self.logger.fatal('KEYMAT not configured correctly.') raise OSError('KEYMAT not configured correctly.') else: super().__init__(settings.EQ_USER_AUTHENTICATION_SR_PRIVATE_KEY, settings.EQ_USER_AUTHENTICATION_SR_PRIVATE_KEY_PASSWORD) # oddly the python cryptography library needs these as bytes string rrm_public_key_as_bytes = strings.to_bytes(settings.EQ_USER_AUTHENTICATION_RRM_PUBLIC_KEY) self.rrm_public_key = serialization.load_pem_public_key( rrm_public_key_as_bytes, backend=backend, )
def __init__(self, private_key, private_key_password, public_key): # pylint: disable=maybe-no-member # password and key variables are dynamically assigned if private_key and private_key_password and public_key: super().__init__(private_key, private_key_password) # oddly the python cryptography library needs these as bytes string rrm_public_key_as_bytes = strings.to_bytes(public_key) self.rrm_public_key = serialization.load_pem_public_key( rrm_public_key_as_bytes, backend=backend, ) else: raise OSError('keymat not configured correctly')
def generate_id(self, metadata): if metadata is None: raise ValueError('metadata is required') collection_exercise_sid, eq_id, form_type, ru_ref = UserIDGenerator._get_token_data( metadata) logger.debug('generating user id', ru_ref=ru_ref, ce_id=collection_exercise_sid, eq_id=eq_id, form_type=form_type) salt = to_bytes(self._user_id_salt) user_id = self._generate(collection_exercise_sid, eq_id, form_type, ru_ref, salt) return to_str(user_id)
def generate_ik(self, token): if token is None: raise ValueError('token is required') collection_exercise_sid, eq_id, form_type, ru_ref = UserIDGenerator._get_token_data( token) logger.debug('generating user ik', ru_ref=ru_ref, ce_id=collection_exercise_sid, eq_id=eq_id, form_type=form_type) salt = to_bytes(self._user_ik_salt) ik = self._generate(collection_exercise_sid, eq_id, form_type, ru_ref, salt) return to_str(ik)
def _generate_key(user_id, user_ik, pepper): sha256 = hashlib.sha256() sha256.update(to_str(user_id).encode('utf-8')) sha256.update(to_str(user_ik).encode('utf-8')) sha256.update(to_str(pepper).encode('utf-8')) # we only need the first 32 characters for the CEK cek = to_bytes(sha256.hexdigest()[:32]) password = { 'kty': 'oct', 'k': base64url_encode(cek), } return jwk.JWK(**password)
def __init__(self): # pylint: disable=maybe-no-member # password and key variables are dynamically assigned if settings.EQ_USER_AUTHENTICATION_RRM_PUBLIC_KEY is None or settings.EQ_USER_AUTHENTICATION_SR_PRIVATE_KEY is None \ or settings.EQ_USER_AUTHENTICATION_SR_PRIVATE_KEY_PASSWORD is None: logger.error('keymat not configured correctly') raise OSError('keymat not configured correctly') else: super().__init__( settings.EQ_USER_AUTHENTICATION_SR_PRIVATE_KEY, settings.EQ_USER_AUTHENTICATION_SR_PRIVATE_KEY_PASSWORD) # oddly the python cryptography library needs these as bytes string rrm_public_key_as_bytes = strings.to_bytes( settings.EQ_USER_AUTHENTICATION_RRM_PUBLIC_KEY) self.rrm_public_key = serialization.load_pem_public_key( rrm_public_key_as_bytes, backend=backend, )
def encrypt(self, json_data, cek): # 96 bit random IV iv = os.urandom(12) payload = self._base_64_encode(strings.to_bytes(json_data)) jwe_protected_header = self._jwe_protected_header() cipher = Cipher(algorithms.AES(cek), modes.GCM(iv), backend=backend) encryptor = cipher.encryptor() encryptor.authenticate_additional_data(jwe_protected_header) ciphertext = encryptor.update(payload) + encryptor.finalize() tag = encryptor.tag encoded_ciphertext = self._base_64_encode(ciphertext) encoded_tag = self._base_64_encode(tag) # assemble result jwe = jwe_protected_header + b".." + self._base_64_encode(iv) + b"." + encoded_ciphertext + b"." + encoded_tag return strings.to_str(jwe)
def encrypt(self, json_data, cek): # 96 bit random IV iv = os.urandom(12) payload = self._base_64_encode(strings.to_bytes(json_data)) jwe_protected_header = self._jwe_protected_header() cipher = Cipher(algorithms.AES(cek), modes.GCM(iv), backend=backend) encryptor = cipher.encryptor() encryptor.authenticate_additional_data(jwe_protected_header) ciphertext = encryptor.update(payload) + encryptor.finalize() tag = encryptor.tag encoded_ciphertext = self._base_64_encode(ciphertext) encoded_tag = self._base_64_encode(tag) # assemble result jwe = jwe_protected_header + b".." + self._base_64_encode( iv) + b"." + encoded_ciphertext + b"." + encoded_tag return strings.to_str(jwe)
def test_to_bytes_with_none(self): b = strings.to_bytes(None) self.assertEqual(b, None)
def test_to_bytes_with_bytes(self): b = strings.to_bytes(b'def') self.assertEqual(b, b'def')
def test_to_bytes_with_string(self): b = strings.to_bytes('abc') self.assertEqual(b, b'abc')
def generate_ik(self, response_id): salt = to_bytes(self._user_ik_salt) user_ik = self._generate(response_id, salt) return to_str(user_ik)
def test_to_bytes_with_string(self): b = strings.to_bytes("abc") self.assertEqual(b, b"abc")
def _generate(collection_exercise_sid, eq_id, form_type, ru_ref, salt): key_material = ru_ref + collection_exercise_sid + eq_id + form_type kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=salt, iterations=settings.EQ_SERVER_SIDE_STORAGE_USER_ID_ITERATIONS, backend=backend) generated_key = kdf.derive(to_bytes(key_material)) return binascii.hexlify(generated_key)