def test_unwrap_invalid_wrapped_key_length(self, backend): # Keys to unwrap must be at least 24 bytes with pytest.raises(ValueError): keywrap.aes_key_unwrap(b"sixteen_byte_key", b"\x00" * 16, backend) # Keys to unwrap must be a multiple of 8 bytes with pytest.raises(ValueError): keywrap.aes_key_unwrap(b"sixteen_byte_key", b"\x00" * 27, backend)
def test_unwrap_invalid_wrapped_key_length(self, backend): # Keys to unwrap must be at least 24 bytes with pytest.raises(keywrap.InvalidUnwrap): keywrap.aes_key_unwrap(b"sixteen_byte_key", b"\x00" * 16, backend) # Keys to unwrap must be a multiple of 8 bytes with pytest.raises(keywrap.InvalidUnwrap): keywrap.aes_key_unwrap(b"sixteen_byte_key", b"\x00" * 27, backend)
def test_unwrap(self, backend, params): wrapping_key = binascii.unhexlify(params["k"]) wrapped_key = binascii.unhexlify(params["c"]) if params.get("fail") is True: with pytest.raises(keywrap.InvalidUnwrap): keywrap.aes_key_unwrap(wrapping_key, wrapped_key, backend) else: unwrapped_key = keywrap.aes_key_unwrap(wrapping_key, wrapped_key, backend) assert params["p"] == binascii.hexlify(unwrapped_key)
def test_unwrap(self, backend, params): wrapping_key = binascii.unhexlify(params["k"]) wrapped_key = binascii.unhexlify(params["c"]) if params.get("fail") is True: with pytest.raises(keywrap.InvalidUnwrap): keywrap.aes_key_unwrap(wrapping_key, wrapped_key, backend) else: unwrapped_key = keywrap.aes_key_unwrap(wrapping_key, wrapped_key, backend) assert params["p"] == binascii.hexlify(unwrapped_key)
def decrypt(self, token, key=None, cek=None): logger.debug('SYM decrypt') if not key and not cek: raise MissingKey("On of key or cek must be specified") if isinstance(token, JWEnc): jwe = token else: jwe = JWEnc().unpack(token) if len(jwe) != 5: raise WrongNumberOfParts(len(jwe)) if not cek: jek = jwe.encrypted_key() if isinstance(key, SYMKey): try: key = key.key.encode('utf8') except AttributeError: key = key.key # The iv for this function must be 64 bit cek = aes_key_unwrap(key, jek, default_backend()) auth_data = jwe.b64_protected_header() msg = self._decrypt( jwe.headers["enc"], cek, jwe.ciphertext(), auth_data=auth_data, iv=jwe.initialization_vector(), tag=jwe.authentication_tag()) if "zip" in self and self["zip"] == "DEF": msg = zlib.decompress(msg) return msg
def unwrap_key(self, wrapped_key): wrapped_key = six.ensure_binary(wrapped_key) try: plain_text = aes_key_unwrap(self._key, wrapped_key, default_backend()) except InvalidUnwrap as cause: raise JWEError(cause) return plain_text
def unwrap(self, enc_alg, ek, headers, key): op_key = key.get_op_key('unwrapKey') self._check_key(op_key) cek = aes_key_unwrap(op_key, ek, default_backend()) if len(cek) * 8 != enc_alg.CEK_SIZE: raise ValueError('Invalid "cek" length') return cek
def unwrap(self, key, bitsize, ek, headers): rk = self._get_key(key, 'decrypt') cek = aes_key_unwrap(rk, ek, default_backend()) if _bitsize(cek) != bitsize: raise InvalidJWEKeyLength(bitsize, _bitsize(cek)) return cek
def decode_cipher_value(content): """Get user from ACS service response. Args: content (bytes): response.content Returns: tuple: first_name, last_name, DOB, PESEL """ tree = fromstring(content) PUBLIC_KEY = tree.find('.//{http://www.w3.org/2009/xmldsig11#}PublicKey').text CIPHER_VALUE = tree.find('.//{http://www.w3.org/2001/04/xmlenc#}CipherValue').text USER_ATTRS = tree.find('.//{http://www.w3.org/2001/04/xmlenc#}EncryptedData/{http://www.w3.org/2001/04/xmlenc#}CipherData/{http://www.w3.org/2001/04/xmlenc#}CipherValue').text concatKDFParams = tree.find('.//{http://www.w3.org/2009/xmlenc11#}ConcatKDFParams') with open(settings.LOGINGOVPL_ENC_KEY, 'rb') as f: server_private_key = load_pem_private_key( f.read(), None, default_backend(), ) public_key_bytes = base64.b64decode(PUBLIC_KEY) curve = ec.SECP256R1() peer_public_key = ec.EllipticCurvePublicKey.from_encoded_point(curve, public_key_bytes) peer_public_key_pem = peer_public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo, ) logger.debug('peer public key:\n%s', peer_public_key_pem.decode()) shared_key = server_private_key.exchange( ec.ECDH(), peer_public_key) logger.debug('shared key: %s', shared_key) otherinfo = get_otherinfo(concatKDFParams) logger.debug('otherinfo: %s', otherinfo) ckdf = ConcatKDFHash( algorithm=hashes.SHA256(), length=32, otherinfo=binascii.unhexlify(otherinfo.encode()), backend=default_backend() ) cipher_bytes = base64.b64decode(CIPHER_VALUE) wrapping_key = ckdf.derive(shared_key) logger.debug('wrapping key: %s', wrapping_key) session_key = aes_key_unwrap(wrapping_key, cipher_bytes, default_backend()) user_attr_bytes = base64.b64decode(USER_ATTRS) nonce, tag = user_attr_bytes[:12], user_attr_bytes[-16:] cipher = AES.new(session_key, AES.MODE_GCM, nonce) decoded_saml = cipher.decrypt_and_verify(user_attr_bytes[12:-16], tag) logger.debug(decoded_saml) return decoded_saml
def wrap_unwrap(key_1, key_2): # Function to wrap and unwrap keys backend = default_backend() wrapped_key = keywrap.aes_key_wrap( key_2, key_1, backend=backend) # Wrap key 1 with key 2 unwrapped_key = keywrap.aes_key_unwrap( key_2, wrapped_key, backend=backend) # Unwrapped the wrapped key with the key 2 return wrapped_key, unwrapped_key
def aes_key_unwrap(self, kek: bytes, wrapped_key: bytes) -> bytes: """Unwraps a key using a key-encrypting key (KEK). :param kek: The key-encrypting key :param wrapped_key: Encrypted data :return: Un-wrapped key """ return keywrap.aes_key_unwrap(kek, wrapped_key, default_backend())
def test_keywrap(backend, wycheproof): wrapping_key = binascii.unhexlify(wycheproof.testcase["key"]) key_to_wrap = binascii.unhexlify(wycheproof.testcase["msg"]) expected = binascii.unhexlify(wycheproof.testcase["ct"]) if (wycheproof.valid or (wycheproof.acceptable and wycheproof.testcase["comment"] != "invalid size of wrapped key")): result = keywrap.aes_key_wrap(wrapping_key, key_to_wrap, backend) assert result == expected if wycheproof.valid or wycheproof.acceptable: result = keywrap.aes_key_unwrap(wrapping_key, expected, backend) assert result == key_to_wrap else: with pytest.raises(keywrap.InvalidUnwrap): keywrap.aes_key_unwrap(wrapping_key, expected, backend)
def unwrap_key(security_control: SecurityControlField, wrapping_key: bytes, wrapped_key: bytes): """ Simple function to unwrap a key received. """ validate_key(security_control.security_suite, wrapping_key) validate_key(security_control.security_suite, wrapped_key) unwrapped_key = aes_key_unwrap(wrapping_key, wrapped_key) return unwrapped_key
def test_unwrap(self, backend, subtests): params = _load_all_params( os.path.join("keywrap", "kwtestvectors"), ["KW_AD_128.txt", "KW_AD_192.txt", "KW_AD_256.txt"], load_nist_vectors, ) for param in params: with subtests.test(): wrapping_key = binascii.unhexlify(param["k"]) wrapped_key = binascii.unhexlify(param["c"]) if param.get("fail") is True: with pytest.raises(keywrap.InvalidUnwrap): keywrap.aes_key_unwrap(wrapping_key, wrapped_key, backend) else: unwrapped_key = keywrap.aes_key_unwrap( wrapping_key, wrapped_key, backend) assert param["p"] == binascii.hexlify(unwrapped_key)
def test_keywrap(backend, wycheproof): wrapping_key = binascii.unhexlify(wycheproof.testcase["key"]) key_to_wrap = binascii.unhexlify(wycheproof.testcase["msg"]) expected = binascii.unhexlify(wycheproof.testcase["ct"]) if ( wycheproof.valid or ( wycheproof.acceptable and wycheproof.testcase["comment"] != "invalid size of wrapped key" ) ): result = keywrap.aes_key_wrap(wrapping_key, key_to_wrap, backend) assert result == expected if wycheproof.valid or wycheproof.acceptable: result = keywrap.aes_key_unwrap(wrapping_key, expected, backend) assert result == key_to_wrap else: with pytest.raises(keywrap.InvalidUnwrap): keywrap.aes_key_unwrap(wrapping_key, expected, backend)
def unwrap_key_aes(key_to_unwrap, wrapping_key): """ Unwraps a key using the AES key wrapping mode of operation as specified in https://www.ietf.org/rfc/rfc3394.txt :param key_to_unwrap: the wrapped result of a previous wrap operation. I.e. the key to be unwrapped :param wrapping_key: the key used to unwrap = KEK. This must be the same key used to wrap :return: the unwrapped key """ return keywrap.aes_key_unwrap(wrapping_key, key_to_unwrap, default_backend())
def dec_setup(self, token, key=None, **kwargs): """ :param token: signed JSON Web token :param key: Private Elliptic Curve Key :param kwargs: :return: """ self.headers = token.headers self.iv = token.initialization_vector() self.ctxt = token.ciphertext() self.tag = token.authentication_tag() # Handle EPK / Curve if "epk" not in self.headers or "crv" not in self.headers["epk"]: raise Exception("Ephemeral Public Key Missing in ECDH-ES Computation") epubkey = ECKey(**self.headers["epk"]) apu = apv = "" if "apu" in self.headers: apu = b64d(self.headers["apu"].encode()) if "apv" in self.headers: apv = b64d(self.headers["apv"].encode()) if self.headers["alg"] == "ECDH-ES": try: dk_len = KEY_LEN[self.headers["enc"]] except KeyError: raise Exception("Unknown key length for algorithm") self.cek = ecdh_derive_key( key, epubkey.pub_key, apu, apv, str(self.headers["enc"]).encode(), dk_len, ) elif self.headers["alg"] in [ "ECDH-ES+A128KW", "ECDH-ES+A192KW", "ECDH-ES+A256KW", ]: _pre, _post = self.headers["alg"].split("+") klen = int(_post[1:4]) kek = ecdh_derive_key(key, epubkey.pub_key, apu, apv, str(_post).encode(), klen) self.cek = aes_key_unwrap(kek, token.encrypted_key(), default_backend()) else: raise Exception("Unsupported algorithm %s" % self.headers["alg"]) return self.cek
def decrypt(self, pk, *args): km = pk.keymaterial # assemble the public component of ephemeral key v v = ec.EllipticCurvePublicNumbers(self.p.x, self.p.y, km.oid.curve()).public_key(default_backend()) # compute s using the inverse of how it was derived during encryption s = km.__privkey__().exchange(ec.ECDH(), v) # derive the wrapping key z = km.kdf.derive_key(s, km.oid, PubKeyAlgorithm.ECDH, pk.fingerprint) # unwrap and unpad m _m = aes_key_unwrap(z, self.c, default_backend()) padder = PKCS7(64).unpadder() return padder.update(_m) + padder.finalize()
def decrypt(self, pk, *args): km = pk.keymaterial # assemble the public component of ephemeral key v v = ec.EllipticCurvePublicNumbers(self.vX, self.vY, km.oid.curve()).public_key(default_backend()) # compute s using the inverse of how it was derived during encryption s = km.__privkey__().exchange(ec.ECDH(), v) # derive the wrapping key z = km.kdf.derive_key(s, km.oid, PubKeyAlgorithm.ECDH, pk.fingerprint) # unwrap and unpad m _m = aes_key_unwrap(z, self.c, default_backend()) padder = PKCS7(64).unpadder() return padder.update(_m) + padder.finalize()
def key_unwrap(self, mechanism, data, wrapping_key, nonce_iv): """ :param mechanism key wrapping mechanism :param data: data to unwrap :param wrapping_key: AES key used to wrap data :param nonce_iv Nonce data :return: unwrapped data Unwrap the encrypted data which has been wrapped using a KeyWrap mechanism. """ if mechanism == WRAP_AES_CBC_PAD or mechanism == WRAP_DES3_CBC_PAD: return self.symmetric_unwrap(data, wrapping_key, nonce_iv=nonce_iv) if mechanism == WRAP_AES_KEY_WRAP: return keywrap.aes_key_unwrap(wrapping_key, data, self.backend) raise ValueError("Unsupported key wrap algorithm: " + mechanism)
def unwrap(self, wrapping_key, wrapped_key): # type: (bytes, bytes) -> bytes """Unwrap key using AES keywrap. :param bytes wrapping_key: Loaded key with which to unwrap :param bytes wrapped_key: Wrapped key to unwrap :returns: Unwrapped key :rtype: bytes """ if self.java_name not in ("AES", "AESWrap"): raise NotImplementedError('"unwrap" is not supported by this cipher') try: return keywrap.aes_key_unwrap(wrapping_key=wrapping_key, wrapped_key=wrapped_key, backend=default_backend()) except Exception: error_message = "Key unwrap failed" _LOGGER.exception(error_message) raise UnwrappingError(error_message)
def unwrap_key(self, key, algorithm): if algorithm == 'A256KW': return aes_key_unwrap(self.kek, key, self.backend) raise ValueError('Unknown key wrap algorithm.')
def decrypt(self, encrypted_data_key) -> bytes: data_key = aes_key_unwrap( wrapping_key=self._key_bytes, wrapped_key=encrypted_data_key, ) return data_key
def key_unwrap(cls, kek: 'SK', data: bytes): if cls.get_key_length() != len(kek.k): raise ValueError("Key has the wrong length") return aes_key_unwrap(wrapping_key=kek.k, wrapped_key=data, backend=default_backend())
def test_unwrap_invalid_key_length(self, backend): with pytest.raises(ValueError): keywrap.aes_key_unwrap(b"badkey", b"\x00" * 24, backend)
def unwrap(self, ek, headers, key): op_key = key.get_op_key('unwrapKey') self._check_key(op_key) cek = aes_key_unwrap(op_key, ek, default_backend()) return cek
def unwrap_key(self, key, algorithm): if algorithm == 'A256KW': return aes_key_unwrap(self.kek, key, self.backend) else: raise ValueError(_ERROR_UNKNOWN_KEY_WRAP_ALGORITHM)
def unwrap_key(self, key, algorithm): if algorithm == 'A256KW': return aes_key_unwrap(self.kek, key, self.backend) else: raise ValueError(_ERROR_UNKNOWN_KEY_WRAP_ALGORITHM)
def transform(self, data): aes_key_unwrap(self._key, data, default_backend())
def unwrap_key(self, wrapping_key, key_to_unwrap): try: return aes_key_unwrap(wrapping_key, key_to_unwrap, default_backend()) except InvalidUnwrap: raise WrongPassword("Password is incorrect.")
def unwrap(self, ek, headers, key): self._check_key(key) cek = aes_key_unwrap(key, ek, default_backend()) return cek
def unwrap_data_key(self, wrapped_data_key: bytes) -> bytes: return aes_key_unwrap( wrapping_key=self._wrapping_key, wrapped_key=wrapped_data_key, )
def AESKeyWrap(): print("\n\n\n===========================================") print("Welcome to Key Wrap (KW) Mode of Operation") print("===========================================") print(" ") print( "Key wrapping and un-wrapping requires 3 parameters in order to function correctly:\n" ) print( "\n1) The key encrytion key or 'the wrapping key', which must be of 16, 24 or 32 bytes in value in order for AES to function." ) print( "2) The key that is to be wrapped 'key to wrap', this is also of 16, 24 or 32 bytes in value." ) print( "3) Finally, the wrapped key, this is the encrypted value of the key which is also used in the unwrapping process." ) print( "\nFor simplicity's sake, we have already defined a value for the key encryption key to be b'1234567890123456'." ) wrappingKey = b'1234567890123456' # Must be 16,24,32 bytes userYN = input("Do you wish to change this value?(y/n):") if (userYN == "y"): wrappingKey = input( "Enter a new value for the wrapping key(MUST BE OF 16, 24 OR 32 BYTES):" ) wrappingKey = wrappingKey.encode('utf-8') while (True): if ((len(wrappingKey) % 8 == 0) and len(wrappingKey) >= 16 and len(wrappingKey) <= 32): break print("The wrapping key must be a valid AES key length") wrappingKey = input( "Enter a new value for the wrapping key.(MUST BE OF 16, 24 OR 32 BYTES):" ) wrappingKey = wrappingKey.encode('utf-8') print( "\nAnd again, for simplicity's sake we've defined the key that is to be wrapped to be b'wow-this-is-fun!'" ) keyToWrap = b'wow-this-is-fun!' # Must be 16,24,32 bytes userYN = input("Do you wish to change this value?(y/n):") if (userYN == "y"): keyToWrap = input( "Enter a new value for key to be wrapped.(MUST BE OF 16, 24 OR 32 BYTES):" ) keyToWrap = keyToWrap.encode('utf-8') while (True): if ((len(keyToWrap) % 8 == 0) and len(keyToWrap) >= 16 and len(keyToWrap) <= 32): break print("The wrapping key must be a valid AES key length") keyToWrap = input( "Enter a new value for the wrapping key(MUST BE OF 16, 24 OR 32 BYTES):" ) keyToWrap = keyToWrap.encode('utf-8') wrappedKey = keywrap.aes_key_wrap(wrappingKey, keyToWrap, backend=default_backend()) print("\nThe encrypted value for the wrapped key is:", wrappedKey) input("Press Enter to see how we computed the wrapped key value...") print("\nWhat just happened?") print("-------------------------------------") print( "\nSo to go over how we got the encrypted value, lets take a moment to recall all the components involved." ) print( "First off, when the program asked about setting a key encryption key, this key value is what's going to remain constant in both wrapping and un-wrapping the new key (Defaulted to b'1234567890123456' if no input)." ) print( "The 'new key' is essentially the symmetric key we are wrapping so that we have a safe transfer of keys from the sender side to the receiver." ) print( "This 'new key', we will dub it as the 'keyToWrap' value and this is the second value the program asked for your input. It was defaulted to b'wow-this-is-fun!' if there was no input." ) print("\nSo now we have the following: ") print( "1) Key Encryption Key 'wrappinKey' = b'1234567890123456' or whatever you inputted." ) print( "2) New Symmetric Key 'keyToWrap' = b'wow-this-is-fun!' or whatever you inputted." ) print( "\nFinally, the program used the 'wrappingKey' to encrypt the 'keyToWrap' and that's how we got our 'WrappedKey' value." ) print("To clarify, the wrapped key is:", wrappedKey) input( "Press Enter to see how we can return back to our 'keyToWrap' value..." ) print("\nWhat about un-wrapping?") print("-------------------------------------") print( "\nNow if we wanted to get back our 'keyToWrap' which would be the symmetric key we wanted to exchange, it is actually quite simple given the parameters and values." ) print( "This is most helpful when trying to decrypt the wrapped key as the receiver of the new symmetric key." ) print( "\nJust like what we stated above when figuring out our wrapped key value, lets see what we have:" ) print( "1) Key Encrytion key 'wrappingKey' = b'1234567890123456' or whatever it was you inputted. (REMEMBER THIS PARAMETER REMAINS CONSTANT FOR BOTH OPERATIONS)" ) print("2) 'wrappedKey' = ", wrappedKey) print( "\nJust like before, using the two values and then decrypting using AES, we get back our 'keyToWrap' value" ) c = keywrap.aes_key_unwrap(wrappingKey, wrappedKey, backend=default_backend()) print( "After decrypting we end up with the symmetric key that was to be exchanged between sender and receiver:", c)
def key_unwrap(wrapping_key, wrapped_key): return aes_key_unwrap(wrapping_key, wrapped_key, _BACKEND)
def test_unwrap_invalid_key_length(self, backend): with pytest.raises(ValueError): keywrap.aes_key_unwrap(b"badkey", b"\x00" * 24, backend)
def unwrap_key(self, wrapping_key, key_to_unwrap): try: return aes_key_unwrap(wrapping_key, key_to_unwrap, default_backend()) except InvalidUnwrap: raise WrongPassword("Password is incorrect.")
def unwrap_key(self, wrapped_key: bytes) -> bytes: try: return aes_key_unwrap(self._key, wrapped_key) except Exception as err: raise DecodeError("Failed to unwrap key.") from err