Example #1
0
    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)
Example #2
0
    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)
Example #3
0
 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)
Example #4
0
 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)
Example #5
0
    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
Example #7
0
 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
Example #8
0
    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
Example #9
0
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
Example #11
0
    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)
Example #13
0
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
Example #14
0
 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)
Example #15
0
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)
Example #16
0
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())
Example #17
0
    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
Example #18
0
    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()
Example #19
0
    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()
Example #20
0
    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)
Example #21
0
    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)
Example #22
0
 def unwrap_key(self, key, algorithm):
     if algorithm == 'A256KW':
         return aes_key_unwrap(self.kek, key, self.backend)
     raise ValueError('Unknown key wrap algorithm.')
Example #23
0
 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
Example #24
0
 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())
Example #25
0
 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
Example #27
0
 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)
Example #29
0
 def transform(self, data):
     aes_key_unwrap(self._key, data, default_backend())
Example #30
0
 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.")
Example #31
0
 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)
Example #34
0
def key_unwrap(wrapping_key, wrapped_key):
    return aes_key_unwrap(wrapping_key, wrapped_key, _BACKEND)
Example #35
0
 def test_unwrap_invalid_key_length(self, backend):
     with pytest.raises(ValueError):
         keywrap.aes_key_unwrap(b"badkey", b"\x00" * 24, backend)
Example #36
0
 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.")
Example #37
0
 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