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_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 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: 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 _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 decrypt_jwt_token(self, token): try: if token: logging.debug("Decrypting signed JWT " + strings.to_str(token)) tokens = token.split('.') if len(tokens) != 5: raise InvalidTokenException("Incorrect size") jwe_protected_header = tokens[0] self.__check_jwe_protected_header(jwe_protected_header) encrypted_key = tokens[1] encoded_iv = tokens[2] decrypted_key = self._decrypt_key(encrypted_key) iv = self._base64_decode(encoded_iv) if not self._check_iv_length(iv): raise InvalidTokenException("IV incorrect length") if not self._check_cek_length(decrypted_key): raise InvalidTokenException("CEK incorrect length") signed_token = super().decrypt(token) return self.decode_signed_jwt_token(signed_token) else: raise NoTokenException("JWT Missing") except (jwt.DecodeError, InvalidTag, InternalError, ValueError, AssertionError) as e: raise InvalidTokenException(repr(e))
def _check_token(self, token): token_as_str = strings.to_str(token) if token_as_str.count(".") != 2: raise InvalidTokenException("Invalid Token") self._check_headers(token_as_str) self._check_payload(token_as_str) return
def decrypt(self, token, cek): tokens = token.split('.') if len(tokens) != 5: raise ValueError("Incorrect size") jwe_protected_header = tokens[0] # encrypted_key is not used, would be tokens[1] encoded_iv = tokens[2] encoded_cipher_text = tokens[3] encoded_tag = tokens[4] iv = self._base64_decode(encoded_iv) tag = self._base64_decode(encoded_tag) cipher_text = self._base64_decode(encoded_cipher_text) decrypted_text = self._decrypt_cipher_text(cipher_text, iv, cek, tag, jwe_protected_header) decoded_text = self._base64_decode(strings.to_str(decrypted_text)) return strings.to_str(decoded_text)
def _check_token(self, token): token_as_str = strings.to_str(token) if token_as_str.count(".") != 2: raise InvalidTokenException("Invalid Token") # header_data, payload_data, signature_data header_data, payload_data, _ = token_as_str.split('.', maxsplit=2) self._check_headers(header_data) self._check_header_values(token_as_str) self._check_payload(payload_data)
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_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_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 decode_signed_jwt_token(self, signed_token, leeway): try: if signed_token: logger.debug("decoding signed jwt", jwt_token=strings.to_str(signed_token)) self._check_token(signed_token) token = jwt.decode(signed_token, self.rrm_public_key, algorithms=['RS256'], leeway=leeway) if not token: raise InvalidTokenException("Missing Payload") return token else: raise NoTokenException("JWT Missing") except (jwt.DecodeError, jwt.exceptions.InvalidAlgorithmError, jwt.exceptions.ExpiredSignatureError, jwt.exceptions.InvalidIssuedAtError) as e: raise InvalidTokenException(repr(e))
def decode_signed_jwt_token(self, signed_token): try: if signed_token: logging.debug("Decoding signed JWT " + strings.to_str(signed_token)) self._check_token(signed_token) token = jwt.decode(signed_token, self.rrm_public_key, algorithms=['RS256'], leeway=settings.EQ_JWT_LEEWAY_IN_SECONDS) if not token: raise InvalidTokenException("Missing Payload") return token else: raise NoTokenException("JWT Missing") except (jwt.DecodeError, jwt.exceptions.InvalidAlgorithmError, jwt.exceptions.ExpiredSignatureError, jwt.exceptions.InvalidIssuedAtError) as e: raise InvalidTokenException(repr(e))
def encrypt(self, json): payload = self._encode_and_signed(json) jwe_protected_header = self._jwe_protected_header() encrypted_key = self._encrypted_key(self.cek) cipher = Cipher(algorithms.AES(self.cek), modes.GCM(self.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"." + encrypted_key + b"." + self._encode_iv(self.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 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_string_with_bytes(self): s = strings.to_str(b'klm') self.assertEqual(s, 'klm')
def _check_for_duplicates(self, headers): headers_as_str = strings.to_str(headers) json.loads(headers_as_str, object_pairs_hook=self._raise_exception_on_duplicates)
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_string_with_None(self): s = strings.to_str(None) self.assertEqual(s, None)
def test_to_string_with_string(self): s = strings.to_str("hij") self.assertEqual(s, "hij")
def test_to_string_with_bytes(self): s = strings.to_str(b"klm") self.assertEqual(s, "klm")
def test_to_string_with_string(self): s = strings.to_str('hij') self.assertEqual(s, 'hij')