Example #1
0
    def encrypt_with_hmac(self, data, data_id, iv):
        if not isinstance(data, bytes):
            raise TypeError("data must be bytes.")

        if not isinstance(data_id, int):
            raise TypeError("data_id must be int.")

        main_parts = (
            struct.pack(config.FORMAT_CHAR, data_id) + data
        )

        # PKCS7 padding
        padded_data = self.add_padding(main_parts, algorithms.AES.block_size)
        # AES with CBC mode
        encryptor = Cipher(algorithms.AES(self.aes_key), modes.CBC(iv), backend=self.backend).encryptor()
        ciphertext = encryptor.update(padded_data) + encryptor.finalize()

        basic_parts = (
            b"\x80" + iv + ciphertext
        )

        h = HMAC(self.mac_key, hashes.SHA256(), backend=self.backend)
        h.update(basic_parts)
        hmac = h.finalize()
        return basic_parts + hmac
Example #2
0
def encrypt(pubkey, data):
    public_key = _pub_to_public(pubkey)
    private_key = ec.generate_private_key(ec.SECP256K1(), openssl.backend)
    secret = private_key.exchange(ec.ECDH(), public_key)
    key = hashlib.sha512(secret).digest()
    enckey = key[0:32]
    mackey = key[32:64]
    iv = os.urandom(16)
    padder = padding.PKCS7(128).padder()
    paddeddata = padder.update(data) + padder.finalize()
    cipher = Cipher(algorithms.AES(enckey), modes.CBC(iv), openssl.backend)
    encryptor = cipher.encryptor()
    ciphertext = encryptor.update(paddeddata) + encryptor.finalize()
    s = serialize.Serializer()
    s.bytes(iv)
    s.uint(0x02ca, 2)
    public_numbers = private_key.public_key().public_numbers()
    x = public_numbers.x.to_bytes(32, 'big').lstrip(b'\x00')
    s.uint(len(x), 2)
    s.bytes(x)
    y = public_numbers.y.to_bytes(32, 'big').lstrip(b'\x00')
    s.uint(len(y), 2)
    s.bytes(y)
    s.bytes(ciphertext)
    maccer = HMAC(mackey, hashes.SHA256(), openssl.backend)
    maccer.update(s.data)
    mac = maccer.finalize()
    s.bytes(mac)
    return s.data
    def checkHMAC(self, fp, segments_start, segments_end, fileHMAC):
        '''Check the file's integrity'''
        filehash = HMAC(self.hmackey, primitives.hashes.SHA256(), backend)
        filehash.update(self.FileMACPrefix)
        for segmentIndex, startpos, datalen in self.segment_ranges(segments_start, segments_end):

            print("        Segment %d" % (segmentIndex))
            fp.seek(startpos)
            segmentIV = fp.read(self.SegIVLen)
            segmentMAC = fp.read(self.SegMACLen)

            # Verify the segment's own MAC against the segment data
            segmenthash = HMAC(self.hmackey, primitives.hashes.SHA256(), backend)
            segmenthash.update(segmentIV)
            segmenthash.update(struct.pack('>I', segmentIndex))
            segmenthash.update(fp.read(datalen))

            # The cryptography module doesn't handle truncated HMACs directly
            computed = segmenthash.finalize()
            assert primitives.constant_time.bytes_eq(computed[:self.SegMACLen], segmentMAC)

            # Add the segment's MAC to the file-MAC context
            filehash.update(segmentMAC)

        # Finally, verify the file MAC
        print("        File hash")
        filehash.verify(fileHMAC) # Raises on mismatch.
Example #4
0
def _get_hmac(key, ciphertext, digest_method):
    hmac = HMAC(
        key,
        get_digest(digest_method),
        backend=default_backend()
    )
    hmac.update(ciphertext)
    return hmac.finalize()
Example #5
0
class Decryptor(object):
    def __init__(self, rsa_private_key_pem):
        if not isinstance(rsa_private_key_pem, bytes):
            rsa_private_key_pem = rsa_private_key_pem.encode("ascii")
        self.rsa_private_key = serialization.load_pem_private_key(
            data=rsa_private_key_pem,
            password=None,
            backend=default_backend())
        self.cipher = None
        self.authenticator = None
        self.buf = b""

    def update(self, data):
        self.buf += data
        if self.cipher is None:
            if len(self.buf) < 8:
                return b""
            if self.buf[0:6] != FILEMAGIC:
                raise EncryptorError("Invalid magic bytes")
            cipherkeylen = struct.unpack(">H", self.buf[6:8])[0]
            if len(self.buf) < 8 + cipherkeylen:
                return b""
            pad = padding.OAEP(mgf=padding.MGF1(algorithm=SHA1()),
                               algorithm=SHA1(),
                               label=None)
            try:
                plainkey = self.rsa_private_key.decrypt(self.buf[8:8 + cipherkeylen], pad)
            except AssertionError:
                raise EncryptorError("Decrypting key data failed")
            if len(plainkey) != 64:
                raise EncryptorError("Integrity check failed")
            key = plainkey[0:16]
            nonce = plainkey[16:32]
            auth_key = plainkey[32:64]

            self.cipher = Cipher(algorithms.AES(key), modes.CTR(nonce), backend=default_backend()).decryptor()
            self.authenticator = HMAC(auth_key, SHA256(), backend=default_backend())
            self.buf = self.buf[8 + cipherkeylen:]

        if len(self.buf) < 32:
            return b""

        self.authenticator.update(self.buf[:-32])
        result = self.cipher.update(self.buf[:-32])
        self.buf = self.buf[-32:]

        return result

    def finalize(self):
        if self.cipher is None:
            return b""  # empty encrypted input yields empty plaintext output
        elif self.buf != self.authenticator.finalize():
            raise EncryptorError("Integrity check failed")
        result = self.cipher.finalize()
        self.buf = b""
        self.cipher = None
        self.authenticator = None
        return result
Example #6
0
def calculate_hmac(key, data):
    """Shortcut for calculating HMAC of a string."""
    h = HMAC(
        key=key,
        algorithm=hashes.SHA256(),
        backend=backend
    )
    h.update(data)
    return h.finalize()
Example #7
0
  def __init__(self, key, backend=None):
    if backend is None:
      backend = default_backend()

    key = base64.urlsafe_b64decode(key)
    if len(key) != 32:
      raise ValueError(
        "Fernet key must be 32 url-safe base64-encoded bytes."
    )

    h = HMAC(key, hashes.SHA256(), backend=backend)
    h.update(b"\x00")
    self._signing_key = h.finalize()[:16]

    h = HMAC(key, hashes.SHA256(), backend=backend)
    h.update(b"\x01")
    self._encryption_key = h.finalize()[:16]

    self._backend = backend
Example #8
0
 def generate_mac(key, data, algorithm="SHA256", backend=BACKEND):
     """ Returns a message authentication code for verifying the integrity and
         authenticity of data by entities that possess the key. 
         
         Note this is a lower level function then apply_mac and
         only returns the mac itself. 
         
         The mac is generated via HMAC with the specified algorithm and key. """
     hasher = HMAC(key, getattr(hashes, algorithm.upper())(), backend=backend)
     hasher.update(algorithm + '::' + data)
     return hasher.finalize()
Example #9
0
    def compute_verify_data(self, basekey, handshake_context):
        hash_len = self.hash.digest_size
        finished_key = self.expand_label(basekey, b"finished", b"", hash_len)

        h = Hash(self.hash, backend=default_backend())
        h.update(handshake_context)
        hash_value = h.finalize()

        hm = HMAC(finished_key, self.hash, default_backend())
        hm.update(hash_value)
        return hm.finalize()
Example #10
0
File: prf.py Project: ashfall/tls
def _a(secret, hash_algorithm, n, seed):
    """
    a() is defined as:
        a(0) = seed
        a(i) = HMAC_hash(secret, A(i-1))
    """
    if n == 0:
        return seed
    else:
        h = HMAC(secret, hash_algorithm, default_backend())
        h.update(_a(secret, hash_algorithm, n - 1, seed))
        return h.finalize()
Example #11
0
 def generate_mac(key, data, algorithm="SHA256", backend=BACKEND):
     """ Returns a message authentication code for verifying the integrity and
         authenticity of data by entities that possess the key. 
         
         Note this is a lower level function then apply_mac and
         only returns the mac itself. 
         
         The mac is generated via HMAC with the specified algorithm and key. """
     hasher = HMAC(key,
                   getattr(hashes, algorithm.upper())(),
                   backend=backend)
     hasher.update(algorithm + '::' + data)
     return hasher.finalize()
Example #12
0
    def _encrypt_cryptography(b_plaintext, b_key1, b_key2, b_iv):
        cipher = C_Cipher(algorithms.AES(b_key1), modes.CTR(b_iv), CRYPTOGRAPHY_BACKEND)
        encryptor = cipher.encryptor()
        padder = padding.PKCS7(algorithms.AES.block_size).padder()
        b_ciphertext = encryptor.update(padder.update(b_plaintext) + padder.finalize())
        b_ciphertext += encryptor.finalize()

        # COMBINE SALT, DIGEST AND DATA
        hmac = HMAC(b_key2, hashes.SHA256(), CRYPTOGRAPHY_BACKEND)
        hmac.update(b_ciphertext)
        b_hmac = hmac.finalize()

        return to_bytes(hexlify(b_hmac), errors='surrogate_or_strict'), hexlify(b_ciphertext)
Example #13
0
    def _encrypt_cryptography(b_plaintext, b_key1, b_key2, b_iv):
        cipher = C_Cipher(algorithms.AES(b_key1), modes.CTR(b_iv), CRYPTOGRAPHY_BACKEND)
        encryptor = cipher.encryptor()
        padder = padding.PKCS7(algorithms.AES.block_size).padder()
        b_ciphertext = encryptor.update(padder.update(b_plaintext) + padder.finalize())
        b_ciphertext += encryptor.finalize()

        # COMBINE SALT, DIGEST AND DATA
        hmac = HMAC(b_key2, hashes.SHA256(), CRYPTOGRAPHY_BACKEND)
        hmac.update(b_ciphertext)
        b_hmac = hmac.finalize()

        return to_bytes(hexlify(b_hmac), errors='surrogate_or_strict'), hexlify(b_ciphertext)
Example #14
0
File: prf.py Project: ashfall/tls
def _p_hash(hash_algorithm, secret, seed, output_length):
    """
    A seed expansion function that uses a single hash function to expand a
    secret and seed into the number of bytes specified by output_length.
    """
    result = bytearray()
    i = 1
    while len(result) < output_length:
        h = HMAC(secret, hash_algorithm, default_backend())
        h.update(_a(secret, hash_algorithm, i, seed))
        h.update(seed)
        result.extend(h.finalize())
        i += 1
    return bytes(result[:output_length])
Example #15
0
def MyencryptMAC(message, EncKey, HMACKey):
    # encrypts message with encryption key
    c, iv = myencrypt(message, EncKey)

    if len(HMACKey) != KEY_BYTES:
        # prints error message
        sys.stderr.write('Error: HMAC key length must be 32 bytes.')
    else:
        # generates tag using HMAC on ciphertext generated above
        tag = HMAC(HMACKey, hashes.SHA256(), backend=default_backend())
        tag.update(c)
        tag = tag.finalize()

        return c, iv, tag
Example #16
0
    def __init__(self, key, backend=None):
        if backend is None:
            backend = default_backend()

        # initialize a fernet object
        self._f = Fernet(key, backend=backend)

        key = base64.urlsafe_b64decode(key)
        if len(key) != 32:
            raise ValueError(
                "Fernet2 key must be 32 url-safe base64-encoded bytes.")

        h0 = HMAC(key, hashes.SHA256(), backend=backend)
        h1 = HMAC(key, hashes.SHA256(), backend=backend)
        #
        h0.update(b"0")
        h1.update(b"1")
        k0 = h0.finalize()[:16]
        k1 = h1.finalize()[:16]

        self._signing_key = k0
        self._encryption_key = k1
        self._backend = backend
Example #17
0
def _p_hash(hash_algorithm, secret, seed, output_length):
    """
    A seed expansion function that uses a single hash function to expand a
    secret and seed into the number of bytes specified by output_length.
    """
    result = bytearray()
    i = 1
    while len(result) < output_length:
        h = HMAC(secret, hash_algorithm, default_backend())
        h.update(_a(secret, hash_algorithm, i, seed))
        h.update(seed)
        result.extend(h.finalize())
        i += 1
    return bytes(result[:output_length])
Example #18
0
    def _encrypt_from_parts(self, data, seed, iv):
        utils._check_bytes("data", data)

        padder = padding.PKCS7(algorithms.AES.block_size).padder()
        padded_data = padder.update(data) + padder.finalize()
        encryptor = Cipher(algorithms.AES(self._encryption_key), modes.CBC(iv),
                           self._backend).encryptor()
        ciphertext = encryptor.update(padded_data) + encryptor.finalize()

        basic_parts = (b"\x80" + struct.pack(">Q", seed) + iv + ciphertext)

        h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
        h.update(basic_parts)
        hmac = h.finalize()
        return base64.urlsafe_b64encode(basic_parts + hmac).decode()
Example #19
0
    def __init__(self, key, backend=None):
        if backend is None:
            backend = default_backend()

        # initialize a fernet object
        self._f = Fernet(key, backend=backend)

        key = base64.urlsafe_b64decode(key)
        if len(key) != 32:
            raise ValueError(
                "Fernet2 key must be 32 url-safe base64-encoded bytes."
            )

        h0 = HMAC(key, hashes.SHA256(), backend=backend)
        h1 = HMAC(key, hashes.SHA256(), backend=backend)
        # 
        h0 .update(b"0")
        h1 .update(b"1")
        k0 = h0.finalize()[:16]
        k1 = h1.finalize()[:16]

        self._signing_key = k0
        self._encryption_key = k1
        self._backend = backend
    def _hmac_signature(self, work_bytes):
        try:
            iv = six.binary_type(work_bytes[self.IV_START:self.IV_SIZE])
            payload = six.binary_type(
                work_bytes[self.PAYLOAD_START:self.SIGNATURE_RSTART])

            h = HMAC(self._keys.integrity_key,
                     self.KEY_ALGORITHM(),
                     backend=self._backend)
            h.update(payload)
            h.update(iv)
            hmac = h.finalize()
            return hmac[0:4]
        except Exception:
            raise SignatureException
Example #21
0
    def _encrypt_from_parts(self, data, current_time, iv):
        if isinstance(data, six.text_type):
            raise TypeError("Unicode-objects must be encoded before encryption")

        padder = padding.PKCS7(algorithms.AES.block_size).padder()
        padded_data = padder.update(data) + padder.finalize()
        encryptor = Cipher(algorithms.AES(self._encryption_key), modes.CBC(iv), self._backend).encryptor()
        ciphertext = encryptor.update(padded_data) + encryptor.finalize()

        basic_parts = b"\x80" + struct.pack(">Q", current_time) + iv + ciphertext

        h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
        h.update(basic_parts)
        hmac = h.finalize()
        return base64.urlsafe_b64encode(basic_parts + hmac)
Example #22
0
    def encrypt(cls, data: bytes, key: SSSSKey, name: str, iv: Optional[IV] = None) -> SSSSData:
        if iv:
            ivb = bytearray(iv)
        else:
            ivb = bytearray(secrets.token_bytes(16))

        ivb[8] = ivb[8] & 0x7f;
        iv = IV(bytes(ivb))

        keys = key.derive_keys(name)
        ct = aes256ctr(iv, keys.aes_key, data)

        hm = HMAC(keys.hmac_key, SHA256(), backend = default_backend())
        hm.update(ct)
        mac = MAC(hm.finalize())

        return cls(mac, iv, ct)
Example #23
0
    def _encrypt_from_parts(self, data, current_time, iv):
        if not isinstance(data, bytes):
            raise TypeError("data must be bytes.")

        padder = padding.PKCS7(algorithms.AES.block_size).padder()
        padded_data = padder.update(data) + padder.finalize()
        encryptor = Cipher(algorithms.AES(self._encryption_key), modes.CBC(iv),
                           self._backend).encryptor()
        ciphertext = encryptor.update(padded_data) + encryptor.finalize()

        basic_parts = (b"\x80" + struct.pack(">Q", current_time) + iv +
                       ciphertext)

        h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
        h.update(basic_parts)
        hmac = h.finalize()
        return base64.urlsafe_b64encode(basic_parts + hmac)
Example #24
0
def test_decrypt_and_unpack_bad_signature(caplog, mock_open_streams):
    orig, new, _ = mock_open_streams
    orig_contents = orig._fd.getvalue()
    cipher = Cipher(AES(TMP_KEY), CTR(TMP_NONCE),
                    backend=default_backend()).encryptor()
    ct = cipher.update(zlib.compress(orig_contents))
    hmac = HMAC(TMP_KEY, SHA256(), default_backend())
    hmac.update(ct)
    signature = hmac.finalize()
    orig._fd.write(ct)
    with pytest.raises(BackupCorruptedError):
        decrypt_and_unpack(
            orig,
            new,
            TMP_KEYPAIR + signature[:-2] + b'f',
            dict(use_compression=True, use_encryption=True),
        )
Example #25
0
    def encrypt(self, message):
        iv = urandom(int(self.cipherAlg.block_size / 8))  #generate random iv

        encryptor = Cipher(self.cipherAlg, self.mode(iv),
                           default_backend()).encryptor()
        ct = encryptor.update(message) + encryptor.finalize()  #encryption

        ct, iv = b64encode(ct), b64encode(iv)

        h = HMAC(self.macKey, SHA256(), default_backend())
        h.update(ct + iv)
        mac = h.finalize()  #generate MAC

        return {
            "ct": ct.decode("ascii"),
            "iv_nonce": iv.decode("ascii"),
            "mac": b64encode(mac).decode("ascii")
        }
Example #26
0
    def _encrypt_from_parts(self, data, current_time, iv):
        utils._check_bytes("data", data)

        padder = padding.PKCS7(algorithms.AES.block_size).padder()
        padded_data = padder.update(data) + padder.finalize()
        encryptor = Cipher(
            algorithms.AES(self._encryption_key), modes.CBC(iv), self._backend
        ).encryptor()
        ciphertext = encryptor.update(padded_data) + encryptor.finalize()

        basic_parts = (
            b"\x80" + struct.pack(">Q", current_time) + iv + ciphertext
        )

        h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
        h.update(basic_parts)
        hmac = h.finalize()
        return base64.urlsafe_b64encode(basic_parts + hmac)
Example #27
0
class FernetEncryptMiddleware(BaseMiddleware):
    """ Encrypt data based on Fernet from the Cryptography library.

        - Algorithm: AES-128
        - Mode: CBC
        - Padding: PKCS#7
        - MAC: SHA-256, Encrypt-then-MAC
        - Key: User-provided or 32-bytes from /dev/urandom
        - IV: 16-bytes from /dev/urandom
        
    """

    writeable = True

    def __init__(self, key=None, iv=None):
        self.key = key or os.urandom(32)
        self.iv = iv or os.urandom(16)

        self.encryptor = Cipher(algorithms.AES(self.key[16:]),
                                modes.CBC(self.iv),
                                backend=default_backend()).encryptor()
        self.padder = padding.PKCS7(algorithms.AES.block_size).padder()
        self.hmac = HMAC(key[:16], hashes.SHA256(), backend=default_backend())
        self.header = False

    def flush(self):
        if self.encryptor:
            data = self.padder.finalize()
            data = self.encryptor.update(data) + self.encryptor.finalize()
            self.encryptor = None
            self.hmac.update(data)
            return data + self.hmac.finalize()
        return b''

    def write(self, data):
        data = self.padder.update(data)
        data = self.encryptor.update(data)
        self.hmac.update(data)

        if not self.header:
            data = self.iv + data
            self.header = True

        return data
Example #28
0
class Encryptor:
    def __init__(self, rsa_public_key_pem):
        if not isinstance(rsa_public_key_pem, bytes):
            rsa_public_key_pem = rsa_public_key_pem.encode("ascii")
        self.rsa_public_key = serialization.load_pem_public_key(
            rsa_public_key_pem, backend=default_backend())
        self.cipher = None
        self.authenticator = None

    def update(self, data):
        ret = b""
        if self.cipher is None:
            key = os.urandom(16)
            nonce = os.urandom(16)
            auth_key = os.urandom(32)
            self.cipher = Cipher(algorithms.AES(key),
                                 modes.CTR(nonce),
                                 backend=default_backend()).encryptor()
            self.authenticator = HMAC(auth_key,
                                      SHA256(),
                                      backend=default_backend())
            pad = padding.OAEP(mgf=padding.MGF1(algorithm=SHA1()),
                               algorithm=SHA1(),
                               label=None)
            cipherkey = self.rsa_public_key.encrypt(key + nonce + auth_key,
                                                    pad)
            ret = FILEMAGIC + struct.pack(">H", len(cipherkey)) + cipherkey
        cur = self.cipher.update(data)
        self.authenticator.update(cur)
        if ret:
            return ret + cur
        else:
            return cur

    def finalize(self):
        if self.cipher is None:
            return b""  # empty plaintext input yields empty encrypted output

        ret = self.cipher.finalize()
        self.authenticator.update(ret)
        ret += self.authenticator.finalize()
        self.cipher = None
        self.authenticator = None
        return ret
def encryptThenMac(data, key):
	#set up keys, current timestamp and initialization vector
	encryptKey = key[16:]
	signKey = key[:16]
	curTime = int(time.time())
	iv = os.urandom(16)
	
	#pad the data and encrypt using AES in CBC mode
	padder = padding.PKCS7(algorithms.AES.block_size).padder()
	paddedData = padder.update(data) + padder.finalize()
	encryptor = Cipher(algorithms.AES(encryptKey), modes.CBC(iv), default_backend()).encryptor()
	cipher = encryptor.update(paddedData) + encryptor.finalize()
	
	#get the HMAC using SHA256 of the combined parts and return everything combined
	parts = (b"\x80" + struct.pack(">Q", curTime) + iv + cipher)
	hasher = HMAC(signKey, hashes.SHA256(), backend=default_backend())
	hasher.update(parts)
	hmac = hasher.finalize()
	return base64.urlsafe_b64encode(parts + hmac)
Example #30
0
    def encrypt(self, message):
        nonce = urandom(16)  #generate random nonce

        encryptor = Cipher(self.cipherAlg(self.key, nonce), None,
                           default_backend()).encryptor()

        ct = encryptor.update(message) + encryptor.finalize()  #encryption

        ct, nonce = b64encode(ct), b64encode(nonce)

        h = HMAC(self.macKey, SHA256(), default_backend())
        h.update(ct + nonce)
        mac = h.finalize()  #generate MAC

        return {
            "ct": ct.decode("ascii"),
            "iv_nonce": nonce.decode("ascii"),
            "mac": b64encode(mac).decode("ascii")
        }
    def _xor_payload_to_hmac_pad(self, work_bytes):
        """
        payload = payload ^ hmac(encryptionKey, initVector || counterBytes)
        """
        payload_size = len(work_bytes) - self.OVERHEAD_SIZE
        sections = (payload_size + self.COUNTER_PAGESIZE -
                    1) // self.COUNTER_PAGESIZE

        if sections > self.COUNTER_SECTIONS:
            raise OverflowError(
                'Payload is {} bytes, exceeds limit of {}'.format(
                    payload_size,
                    self.COUNTER_PAGESIZE * self.COUNTER_SECTIONS))

        iv = six.binary_type(work_bytes[self.IV_START:self.IV_END])
        pad = bytearray(self.COUNTER_PAGESIZE + 3)
        counter_size = 0

        for section in xrange(0, sections):
            section_base = section * self.COUNTER_PAGESIZE
            section_size = min(payload_size - section_base,
                               self.COUNTER_PAGESIZE)
            h = HMAC(self._keys.encryption_key,
                     self.KEY_ALGORITHM(),
                     backend=self._backend)
            h.update(iv)

            if counter_size != 0:
                pad_page = six.binary_type(
                    pad[self.COUNTER_PAGESIZE:(self.COUNTER_PAGESIZE +
                                               counter_size)])
                h.update(pad_page)

            pad[0:self.COUNTER_PAGESIZE] = h.finalize()

            for i in xrange(0, section_size):
                work_bytes[self.PAYLOAD_START + section_base + i] ^= pad[i]

            pad[0:self.COUNTER_PAGESIZE] = b'\x00' * self.COUNTER_PAGESIZE

            if counter_size == 0 or ++pad[self.COUNTER_PAGESIZE +
                                          counter_size - 1] == 0:
                counter_size += 1
Example #32
0
    def _encrypt_from_parts(self, data, current_time, iv):
        if not isinstance(data, bytes):
            raise TypeError("data must be bytes.")

        padder = padding.PKCS7(algorithms.AES.block_size).padder()
        padded_data = padder.update(data) + padder.finalize()
        encryptor = Cipher(
            algorithms.AES(self._encryption_key), modes.CBC(iv), self._backend
        ).encryptor()
        ciphertext = encryptor.update(padded_data) + encryptor.finalize()

        basic_parts = (
            b"\x80" + struct.pack(">Q", current_time) + iv + ciphertext
        )

        h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
        h.update(basic_parts)
        hmac = h.finalize()
        return basic_parts + hmac
Example #33
0
def compress_and_encrypt(
    input_file: IOIter,
    output_file: IOIter,
    key_pair: Optional[bytes],
    options: OptionsDict,
) -> bytes:
    """ Read data from an open file descriptor, and write the compressed, encrypted data to another
    file descriptor; compute the HMAC of the encrypted data to ensure integrity

    :param input_file: an IOIter object to read plaintext data from
    :param output_file: an IOIter object to write compressed ciphertext to
    """
    key, nonce = (key_pair[:AES_KEY_SIZE], key_pair[AES_KEY_SIZE:]) if key_pair else (b'', b'')
    compressobj = zlib.compressobj()
    zip_fn: Callable[[bytes], bytes] = (  # type: ignore
        compressobj.compress if options['use_compression'] else identity
    )
    encrypt_fn: Callable[[bytes], bytes] = (
        Cipher(AES(key), CTR(nonce), backend=default_backend()).encryptor().update
        if options['use_encryption'] else identity
    )
    hmac = HMAC(key, SHA256(), default_backend())

    def last_block() -> Generator[Tuple[bytes, bool], None, None]:
        yield (compressobj.flush(), False) if options['use_compression'] else (b'', False)

    writer = output_file.writer(); next(writer)
    logger.debug2('starting to compress')
    for block, needs_compression in chain(zip(input_file.reader(), repeat(True)), last_block()):
        if needs_compression:
            block = zip_fn(block)
        logger.debug2(f'zip_fn returned {len(block)} bytes')
        block = encrypt_fn(block)
        logger.debug2(f'encrypt_fn returned {len(block)} bytes')
        if options['use_encryption']:
            hmac.update(block)
        writer.send(block)

    if options['use_encryption']:
        return hmac.finalize()
    else:
        return b''
Example #34
0
def test_decrypt_and_unpack_no_compression(caplog, mock_open_streams):
    orig, new, _ = mock_open_streams
    orig_contents = orig._fd.getvalue()
    cipher = Cipher(AES(TMP_KEY), CTR(TMP_NONCE),
                    backend=default_backend()).encryptor()
    ct = cipher.update(orig_contents)
    hmac = HMAC(TMP_KEY, SHA256(), default_backend())
    hmac.update(ct)
    signature = hmac.finalize()
    orig._fd.write(ct)
    decrypt_and_unpack(
        orig,
        new,
        TMP_KEYPAIR + signature,
        dict(use_compression=False, use_encryption=True),
    )

    assert new._fd.getvalue() == orig_contents
    assert count_matching_log_lines('read 2 bytes from /orig', caplog) == 4
    assert count_matching_log_lines('wrote 2 bytes to /new', caplog) == 4
Example #35
0
 def _encrypting_message(self, data, current_value, iv):
     # Get key
     key = base64.urlsafe_b64decode(self.key)
     # Pad data
     padder = padding.PKCS7(algorithms.AES.block_size).padder()
     padded_data = padder.update(data) + padder.finalize()
     # Get encryptor
     encryptor = Cipher(
         algorithms.AES(key[16:]),
         modes.CBC(iv),
         default_backend(),
     ).encryptor()
     # Encrypt text
     ciphertext = encryptor.update(padded_data) + encryptor.finalize()
     basic_parts = b"\x80" + struct.pack(">Q",
                                         current_value) + iv + ciphertext
     h = HMAC(key[:16], hashes.SHA256(), backend=default_backend())
     h.update(basic_parts)
     hmac = h.finalize()
     return base64.urlsafe_b64encode(basic_parts + hmac)
Example #36
0
  def _encrypt_from_parts(self, data, iv, associated_data):
    if not isinstance(data, bytes):
      raise TypeError("data must be bytes.")

    padder = padding.PKCS7(algorithms.AES.block_size).padder()
    padded_data = padder.update(data) + padder.finalize()
    encryptor = Cipher(
        algorithms.AES(self._encryption_key), modes.CBC(iv), self._backend
    ).encryptor()
    ciphertext = encryptor.update(padded_data) + encryptor.finalize()

    basic_parts = (
      b"\x81" + iv + ciphertext + associated_data
    )

    h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
    h.update(basic_parts)
    hmac = h.finalize() # TAG

    return base64.urlsafe_b64encode(b"\x81" + iv + ciphertext + hmac)
Example #37
0
def encryptThenMac(data, key):
    #set up keys, current timestamp and initialization vector
    encryptKey = key[16:]
    signKey = key[:16]
    curTime = int(time.time())
    iv = os.urandom(16)

    #pad the data and encrypt using AES in CBC mode
    padder = padding.PKCS7(algorithms.AES.block_size).padder()
    paddedData = padder.update(data) + padder.finalize()
    encryptor = Cipher(algorithms.AES(encryptKey), modes.CBC(iv),
                       default_backend()).encryptor()
    cipher = encryptor.update(paddedData) + encryptor.finalize()

    #get the HMAC using SHA256 of the combined parts and return everything combined
    parts = (b"\x80" + struct.pack(">Q", curTime) + iv + cipher)
    hasher = HMAC(signKey, hashes.SHA256(), backend=default_backend())
    hasher.update(parts)
    hmac = hasher.finalize()
    return base64.urlsafe_b64encode(parts + hmac)
Example #38
0
def symmetric_decrypt(data, key, hmac_key=None):
    enc_iv, enc_data = data[:16], data[16:]
    decryptor = Cipher(algorithms.AES(key), modes.ECB(), backend).decryptor()
    iv = decryptor.update(enc_iv) + decryptor.finalize()

    decryptor = Cipher(algorithms.AES(key), modes.CBC(iv), backend).decryptor()
    unenc_data = decryptor.update(enc_data) + decryptor.finalize()

    unpadder = PKCS7(128).unpadder()
    unenc_data = unpadder.update(unenc_data) + unpadder.finalize()

    if hmac_key:
        prefix = iv[13:]
        hmac = HMAC(hmac_key, SHA1(), backend)
        hmac.update(prefix + unenc_data)
        hmac_msg = hmac.finalize()
        if hmac_msg[:13] != iv[:13]:
            raise RuntimeError("Unable to decrypt message, HMAC doesn't match. %s:%s" % (hmac_msg, iv))

    return unenc_data
Example #39
0
    def _encrypt_from_parts(self, data, iv, adata=""):
        if not isinstance(data, bytes):
            raise TypeError("data must be bytes.")

        padder = padding.PKCS7(algorithms.AES.block_size).padder()
        padded_data = padder.update(data) + padder.finalize()
        encryptor = Cipher(algorithms.AES(self._encryption_key), modes.CBC(iv),
                           self._backend).encryptor()
        # ctx = AES( iv || msg )
        ctx = encryptor.update(padded_data) + encryptor.finalize()
        basic_parts = (b"\x81" + iv + ctx)
        # print(str(len(basic_parts)), "basic_parts_len == ", basic_parts)
        # print("iv = " + str(len(iv)), iv)
        # print(str(len(ctx)), "ctx == ", ctx)
        # print("adata == " , len(adata), adata)
        h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
        h.update(basic_parts + adata)
        # tag = HMAC( 0x81 || iv || ctx )
        tag = h.finalize()
        # print("tag = " , len(tag))
        return base64.urlsafe_b64encode(basic_parts + tag)
Example #40
0
def test_hmac():
    current_time = int(time.time())
    salt = os.urandom(16)
    ciphertext = b'this is garbelled normally'
    key = pbkdf2_hmac('sha256', b"password", salt, 100000)
    iv = os.urandom(16)
    basic_parts = (b"\x80" + struct.pack(">Q", current_time)
                   + iv + ciphertext)

    enc_key = base64.urlsafe_b64encode(key)
    hmac = HMAC.new(enc_key[:16], digestmod=SHA256)
    hmac.update(basic_parts)
    hmac = hmac.digest()

    from cryptography.hazmat.primitives import hashes
    from cryptography.hazmat.primitives.hmac import HMAC as CHMAC
    from cryptography.hazmat.backends import default_backend

    h = CHMAC(enc_key[:16], hashes.SHA256(), backend=default_backend())
    h.update(basic_parts)
    chmac = h.finalize()
    assert hmac == chmac
Example #41
0
class Encryptor:
    def __init__(self, rsa_public_key_pem):
        if not isinstance(rsa_public_key_pem, bytes):
            rsa_public_key_pem = rsa_public_key_pem.encode("ascii")
        self.rsa_public_key = serialization.load_pem_public_key(rsa_public_key_pem, backend=default_backend())
        self.cipher = None
        self.authenticator = None

    def update(self, data):
        ret = b""
        if self.cipher is None:
            key = os.urandom(16)
            nonce = os.urandom(16)
            auth_key = os.urandom(32)
            self.cipher = Cipher(algorithms.AES(key), modes.CTR(nonce), backend=default_backend()).encryptor()
            self.authenticator = HMAC(auth_key, SHA256(), backend=default_backend())
            pad = padding.OAEP(mgf=padding.MGF1(algorithm=SHA1()),
                               algorithm=SHA1(),
                               label=None)
            cipherkey = self.rsa_public_key.encrypt(key + nonce + auth_key, pad)
            ret = FILEMAGIC + struct.pack(">H", len(cipherkey)) + cipherkey
        cur = self.cipher.update(data)
        self.authenticator.update(cur)
        if ret:
            return ret + cur
        else:
            return cur

    def finalize(self):
        if self.cipher is None:
            return b""  # empty plaintext input yields empty encrypted output

        ret = self.cipher.finalize()
        self.authenticator.update(ret)
        ret += self.authenticator.finalize()
        self.cipher = None
        self.authenticator = None
        return ret
Example #42
0
    def _encrypt_from_parts(self, data, adata="", salt = "", signing_key = "", encryption_key = ""):
        if not isinstance(data, bytes):
            raise TypeError("data must be bytes.")

        # print("signing_key = " + str(len(signing_key)), signing_key)
        # print("encryption_key = " + str(len(encryption_key)), encryption_key)
        padder = padding.PKCS7(algorithms.AES.block_size).padder()
        padded_data = padder.update(data) + padder.finalize()
        encryptor = Cipher(
            algorithms.AES(encryption_key), modes.CBC("0"*16), self._backend
        ).encryptor()
        # ctx = AES( iv || msg )
        ctx = encryptor.update(padded_data) + encryptor.finalize()

        basic_parts = (
            b"\x82" + salt + ctx
        )

        h = HMAC(signing_key, hashes.SHA256(), backend=self._backend)
        h.update(basic_parts + adata)
        # tag = HMAC( 0x81 || iv || ctx )
        tag = h.finalize()
        return base64.urlsafe_b64encode( basic_parts + tag )
Example #43
0
    def signMsg(self, msg, password):
        '''
		Signs the given message. This procedure ensures that a message can not be altered without
		detecting it.
		Parameters:
		- msg [bytes/str]: the message to sign.
		- password [bytes/str]: the password to use for signing the message.
		Return:
		[bytes]: the raw bytes string that contains both the messsage and the signature.
		Usage:
		- signed_msg = self.signMsg("my message", "my password")
		'''
        msg = self.msgToBytes(msg)
        cred = self.getCredentialsFromPassword(
            password, length=self.hash_algorithm.digest_size)
        data = b"\x80" + cred["salt"] + msg
        # Generate the signature. The signature will have the same size as the hash algorithm digest.
        signer = HMAC(cred["key"],
                      self.hash_algorithm,
                      backend=default_backend())
        signer.update(data)
        signature = signer.finalize()
        return data + signature
Example #44
0
    def encrypt_with_hmac(self, data, data_id, iv):
        if not isinstance(data, bytes):
            raise TypeError("data must be bytes.")

        if not isinstance(data_id, int):
            raise TypeError("data_id must be int.")

        main_parts = (struct.pack(config.FORMAT_CHAR, data_id) + data)

        # PKCS7 padding
        padded_data = self.add_padding(main_parts, algorithms.AES.block_size)
        # AES with CBC mode
        encryptor = Cipher(algorithms.AES(self.aes_key),
                           modes.CBC(iv),
                           backend=self.backend).encryptor()
        ciphertext = encryptor.update(padded_data) + encryptor.finalize()

        basic_parts = (b"\x80" + iv + ciphertext)

        h = HMAC(self.mac_key, hashes.SHA256(), backend=self.backend)
        h.update(basic_parts)
        hmac = h.finalize()
        return basic_parts + hmac
Example #45
0
def our_kdf(secret, extra_secret, info, output_len):
    """
    Noise Key derivation function. Outputs a byte sequence that the caller typically splits into multiple variables
    such as a chain variable and cipher context, or two cipher contexts.

    Args:
        secret:       secret for key derivation
        extra_secret: is used to pass a chaining variable to mix into the KDF.
        info:         ensures that applying the KDF to the same secret values will produce independent output,
                        provided 'info' is different.
        output_len:   length out the output

    Returns:
        derived key of output_len bytes (BytesIO)
    """

    # XXX either I used hkdf below wrong and never managed to use it correctly, or the function we're using ain't
    # XXX the RFC5869 HKDF. Anyway, this is compatible with the Java implementation we have.

    output = io.BytesIO()
    t = bytearray(H_LEN)
    for c in range(output_len // H_LEN + 1):
        bs = b''.join((
            info,
            struct.pack('B', c),
            t[:32],
            extra_secret
        ))

        assert len(bs) == len(info) + 1 + 32 + len(extra_secret)

        hmac = HMAC(key=secret, algorithm=SHA512(), backend=backend)
        hmac.update(bs)
        t = hmac.finalize()
        output.write(t)
    output_val = output.getvalue()[:output_len]
    return io.BytesIO(output_val)
Example #46
0
    def _encrypt_from_parts(self, data, iv, adata=""):
        if not isinstance(data, bytes):
            raise TypeError("data must be bytes.")

        padder = padding.PKCS7(algorithms.AES.block_size).padder()
        padded_data = padder.update(data) + padder.finalize()
        encryptor = Cipher(
            algorithms.AES(self._encryption_key), modes.CBC(iv), self._backend
        ).encryptor()
        # ctx = AES( iv || msg )
        ctx = encryptor.update(padded_data) + encryptor.finalize()
        basic_parts = (
            b"\x81" + iv + ctx
        )
        # print(str(len(basic_parts)), "basic_parts_len == ", basic_parts)
        # print("iv = " + str(len(iv)), iv)
        # print(str(len(ctx)), "ctx == ", ctx)
        # print("adata == " , len(adata), adata)
        h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
        h.update(basic_parts+adata)
        # tag = HMAC( 0x81 || iv || ctx )
        tag = h.finalize()
        # print("tag = " , len(tag))
        return base64.urlsafe_b64encode( basic_parts + tag)
Example #47
0
    def sign(self, pairs):
        """
        Generate a signature for a sequence of (key, value) pairs


        @param pairs: The pairs to sign, in order
        @type pairs: Iterable[six.text_type, six.text_type], six.binary_type is deprecated

        @return: The binary signature of this sequence of pairs
        @rtype: six.binary_type
        """
        warning_msg = "Binary values for pairs are deprecated. Use text input instead."
        pairs = [(string_to_text(a, warning_msg), string_to_text(b, warning_msg)) for a, b in pairs]
        kv = kvform.seqToKV(pairs)

        try:
            algorithm = self.hmac_algorithms[self.assoc_type]
        except KeyError:
            raise ValueError(
                'Unknown association type: %r' % (self.assoc_type,))

        hmac = HMAC(self.secret, algorithm, backend=default_backend())
        hmac.update(kv.encode('utf-8'))
        return hmac.finalize()
Example #48
0
    def decrypt_encryption_key_fallback(self):
        """Decrypts the encryption key using the FALLBACK method. In this method, the
        context string, usually "CredEncryption" or "PSEEncryption", is encrypted using
        a derivation of a fixed key hardcoded in CommonCryptoLib, and used as key to
        encrypt the actual encryption key used in the file with the AES cipher.

        :return: Encryption key decrypted
        :rtype: string
        """
        log_lps.debug("Obtaining encryption key with FALLBACK LPS mode")

        digest = Hash(SHA1(), backend=default_backend())
        digest.update(cred_key_lps_fallback)
        hashed_key = digest.finalize()

        hmac = HMAC(hashed_key, SHA1(), backend=default_backend())
        hmac.update(self.context)
        default_key = hmac.finalize()[:16]

        iv = "\x00" * 16
        decryptor = Cipher(algorithms.AES(default_key), modes.CBC(iv), backend=default_backend()).decryptor()
        encryption_key = decryptor.update(self.encrypted_key) + decryptor.finalize()

        return encryption_key
Example #49
0
    def sign(self, pairs):
        """
        Generate a signature for a sequence of (key, value) pairs


        @param pairs: The pairs to sign, in order
        @type pairs: Iterable[six.text_type, six.text_type], six.binary_type is deprecated

        @return: The binary signature of this sequence of pairs
        @rtype: six.binary_type
        """
        warning_msg = "Binary values for pairs are deprecated. Use text input instead."
        pairs = [(string_to_text(a, warning_msg), string_to_text(b, warning_msg)) for a, b in pairs]
        kv = kvform.seqToKV(pairs)

        try:
            algorithm = self.hmac_algorithms[self.assoc_type]
        except KeyError:
            raise ValueError(
                'Unknown association type: %r' % (self.assoc_type,))

        hmac = HMAC(self.secret, algorithm, backend=default_backend())
        hmac.update(kv.encode('utf-8'))
        return hmac.finalize()
Example #50
0
    def decrypt_encryption_key_fallback(self):
        """Decrypts the encryption key using the FALLBACK method. In this method, the
        context string, usually "CredEncryption" or "PSEEncryption", is encrypted using
        a derivation of a fixed key hardcoded in CommonCryptoLib, and used as key to
        encrypt the actual encryption key used in the file with the AES cipher.

        :return: Encryption key decrypted
        :rtype: string
        """
        log_lps.debug("Obtaining encryption key with FALLBACK LPS mode")

        digest = Hash(SHA1(), backend=default_backend())
        digest.update(cred_key_lps_fallback)
        hashed_key = digest.finalize()

        hmac = HMAC(hashed_key, SHA1(), backend=default_backend())
        hmac.update(self.context)
        default_key = hmac.finalize()[:16]

        iv = "\x00" * 16
        decryptor = Cipher(algorithms.AES(default_key), modes.CBC(iv), backend=default_backend()).decryptor()
        encryption_key = decryptor.update(self.encrypted_key) + decryptor.finalize()

        return encryption_key
Example #51
0
    def _encrypt_from_parts(
        self, data: bytes, current_time: int, iv: bytes
    ) -> bytes:
        utils._check_bytes("data", data)

        padder = padding.PKCS7(algorithms.AES.block_size).padder()
        padded_data = padder.update(data) + padder.finalize()
        encryptor = Cipher(
            algorithms.AES(self._encryption_key),
            modes.CBC(iv),
        ).encryptor()
        ciphertext = encryptor.update(padded_data) + encryptor.finalize()

        basic_parts = (
            b"\x80"
            + current_time.to_bytes(length=8, byteorder="big")
            + iv
            + ciphertext
        )

        h = HMAC(self._signing_key, hashes.SHA256())
        h.update(basic_parts)
        hmac = h.finalize()
        return base64.urlsafe_b64encode(basic_parts + hmac)
Example #52
0
def _hmac(key, message, context):
    hmac = HMAC(key, SHA256(), context.crypto)
    hmac.update(message)
    return hmac.finalize()
Example #53
0
 def hmac(secret, digest_type, msg):
     tmp = HMAC(secret, digest_type, default_backend())
     tmp.update(msg)
     return tmp.finalize()
Example #54
0
    def sign(self, method=methods.enveloped, algorithm="rsa-sha256", key=None, passphrase=None, cert=None,
             c14n_algorithm=default_c14n_algorithm, reference_uri=None, key_name=None):
        """
        Sign the data and return the root element of the resulting XML tree.

        :param method:
            ``signxml.methods.enveloped``, ``signxml.methods.enveloping``, or ``signxml.methods.detached``. See the list
            of signature types under `XML Signature Syntax and Processing Version 2.0, Definitions
            <http://www.w3.org/TR/xmldsig-core2/#sec-Definitions>`_.
        :type method: :py:class:`methods`
        :param algorithm:
            Algorithm that will be used to generate the signature, composed of the signature algorithm and the digest
            algorithm, separated by a hyphen. All algorthm IDs listed under the `Algorithm Identifiers and
            Implementation Requirements <http://www.w3.org/TR/xmldsig-core1/#sec-AlgID>`_ section of the XML Signature
            1.1 standard are supported.
        :type algorithm: string
        :param key:
            Key to be used for signing. When signing with a certificate or RSA/DSA/ECDSA key, this can be a string
            containing a PEM-formatted key, or a :py:class:`cryptography.hazmat.primitives.interfaces.RSAPublicKey`,
            :py:class:`cryptography.hazmat.primitives.interfaces.DSAPublicKey`, or
            :py:class:`cryptography.hazmat.primitives.interfaces.EllipticCurvePublicKey` object. When signing with a
            HMAC, this should be a string containing the shared secret.
        :type key:
            string, :py:class:`cryptography.hazmat.primitives.interfaces.RSAPublicKey`,
            :py:class:`cryptography.hazmat.primitives.interfaces.DSAPublicKey`, or
            :py:class:`cryptography.hazmat.primitives.interfaces.EllipticCurvePublicKey` object
        :param passphrase: Passphrase to use to decrypt the key, if any.
        :type passphrase: string
        :param cert:
            X.509 certificate to use for signing. This should be a string containing a PEM-formatted certificate, or an
            array of strings or OpenSSL.crypto.X509 objects containing the certificate and a chain of intermediate
            certificates.
        :type cert: string, array of strings, or array of OpenSSL.crypto.X509 objects
        :param c14n_algorithm:
            Canonicalization (c14n) algorithm to use. Supported algorithms are listed in the class variable
            ``xmldsig.known_c14n_algorithms``.
        :type c14n_algorithm: string
        :param reference_uri:
            Custom reference URI to incorporate into the signature. Only used when ``method`` is set to ``detached``.
        :type reference_uri: string
        :param key_name: Add a KeyName element in the KeyInfo element that may be used by the signer to communicate a
            key identifier to the recipient. Typically, KeyName contains an identifier related to the key pair used to sign
            the message
        :type key_name: string

        :returns: A :py:class:`lxml.etree.Element` object representing the root of the XML tree containing the signature and the payload data.

        To specify the location of an enveloped signature within **data**, insert a `<Signature Id="placeholder"></Signature>`
        element in **data**. This element will be replaced by the generated signature, and excised when generating the digest.
        """
        self.signature_alg = algorithm
        self.key = key
        self._reference_uri = reference_uri

        if not isinstance(method, methods):
            raise InvalidInput("Unknown signature method {}".format(method))

        if isinstance(cert, (str, bytes)):
            cert_chain = [cert]
        else:
            cert_chain = cert

        self.payload_c14n = self._get_payload_c14n(method, c14n_algorithm=c14n_algorithm)

        self.digest = self._get_digest(self.payload_c14n, self._get_digest_method_by_tag(self.digest_alg))

        signed_info = SubElement(self.sig_root, ds_tag("SignedInfo"), nsmap=self.namespaces)
        c14n_method = SubElement(signed_info, ds_tag("CanonicalizationMethod"), Algorithm=c14n_algorithm)
        if self.signature_alg.startswith("hmac-"):
            algorithm_id = self.known_hmac_digest_tags[self.signature_alg]
        else:
            algorithm_id = self.known_signature_digest_tags[self.signature_alg]
        signature_method = SubElement(signed_info, ds_tag("SignatureMethod"), Algorithm=algorithm_id)
        reference = SubElement(signed_info, ds_tag("Reference"), URI=self._reference_uri)
        if method == methods.enveloped:
            transforms = SubElement(reference, ds_tag("Transforms"))
            SubElement(transforms, ds_tag("Transform"), Algorithm=namespaces.ds + "enveloped-signature")
            SubElement(transforms, ds_tag("Transform"), Algorithm=c14n_algorithm)
        digest_method = SubElement(reference, ds_tag("DigestMethod"), Algorithm=self.known_digest_tags[self.digest_alg])
        digest_value = SubElement(reference, ds_tag("DigestValue"))
        digest_value.text = self.digest
        signature_value = SubElement(self.sig_root, ds_tag("SignatureValue"))

        signed_info_c14n = self._c14n(signed_info, algorithm=c14n_algorithm)
        if self.signature_alg.startswith("hmac-"):
            from cryptography.hazmat.primitives.hmac import HMAC
            signer = HMAC(key=self.key,
                          algorithm=self._get_hmac_digest_method_by_tag(self.signature_alg),
                          backend=default_backend())
            signer.update(signed_info_c14n)
            signature_value.text = ensure_str(b64encode(signer.finalize()))
            self.sig_root.append(signature_value)
        elif self.signature_alg.startswith("dsa-") or self.signature_alg.startswith("rsa-") or self.signature_alg.startswith("ecdsa-"):
            if isinstance(self.key, (str, bytes)):
                from cryptography.hazmat.primitives.serialization import load_pem_private_key
                key = load_pem_private_key(self.key, password=passphrase, backend=default_backend())
            else:
                key = self.key

            hash_alg = self._get_signature_digest_method_by_tag(self.signature_alg)
            if self.signature_alg.startswith("dsa-"):
                signer = key.signer(signature_algorithm=hash_alg)
            elif self.signature_alg.startswith("ecdsa-"):
                signer = key.signer(signature_algorithm=ec.ECDSA(algorithm=hash_alg))
            elif self.signature_alg.startswith("rsa-"):
                signer = key.signer(padding=PKCS1v15(), algorithm=hash_alg)
            else:
                raise NotImplementedError()
            signer.update(signed_info_c14n)
            signature = signer.finalize()
            if self.signature_alg.startswith("dsa-"):
                # Note: The output of the DSA signer is a DER-encoded ASN.1 sequence of two DER integers.
                decoded_signature = der_decoder.decode(signature)[0]
                r = decoded_signature.getComponentByPosition(0)
                s = decoded_signature.getComponentByPosition(1)
                signature = long_to_bytes(r).rjust(32, b"\0") + long_to_bytes(s).rjust(32, b"\0")

            signature_value.text = ensure_str(b64encode(signature))

            key_info = SubElement(self.sig_root, ds_tag("KeyInfo"))
            if key_name is not None:
                keyname = SubElement(key_info, ds_tag("KeyName"))
                keyname.text = key_name

            if cert_chain is None:
                self._serialize_key_value(key, key_info)
            else:
                x509_data = SubElement(key_info, ds_tag("X509Data"))
                for cert in cert_chain:
                    x509_certificate = SubElement(x509_data, ds_tag("X509Certificate"))
                    if isinstance(cert, (str, bytes)):
                        x509_certificate.text = strip_pem_header(cert)
                    else:
                        from OpenSSL.crypto import dump_certificate, FILETYPE_PEM
                        x509_certificate.text = dump_certificate(FILETYPE_PEM, cert)
        else:
            raise NotImplementedError()

        if method == methods.enveloped:
            return self.payload
        elif method == methods.enveloping:
            self.sig_root.append(self.payload)
            return self.sig_root
        elif method == methods.detached:
            return self.sig_root
Example #55
0
    def sign(self, data, key=None, passphrase=None, cert=None, reference_uri=None, key_name=None, key_info=None,
             id_attribute=None):
        """
        Sign the data and return the root element of the resulting XML tree.

        :param data: Data to sign
        :type data: String, file-like object, or XML ElementTree Element API compatible object
        :param key:
            Key to be used for signing. When signing with a certificate or RSA/DSA/ECDSA key, this can be a string
            containing a PEM-formatted key, or a :py:class:`cryptography.hazmat.primitives.interfaces.RSAPublicKey`,
            :py:class:`cryptography.hazmat.primitives.interfaces.DSAPublicKey`, or
            :py:class:`cryptography.hazmat.primitives.interfaces.EllipticCurvePublicKey` object. When signing with a
            HMAC, this should be a string containing the shared secret.
        :type key:
            string, :py:class:`cryptography.hazmat.primitives.interfaces.RSAPublicKey`,
            :py:class:`cryptography.hazmat.primitives.interfaces.DSAPublicKey`, or
            :py:class:`cryptography.hazmat.primitives.interfaces.EllipticCurvePublicKey` object
        :param passphrase: Passphrase to use to decrypt the key, if any.
        :type passphrase: string
        :param cert:
            X.509 certificate to use for signing. This should be a string containing a PEM-formatted certificate, or an
            array of strings or OpenSSL.crypto.X509 objects containing the certificate and a chain of intermediate
            certificates.
        :type cert: string, array of strings, or array of OpenSSL.crypto.X509 objects
        :param reference_uri:
            Custom reference URI or list of reference URIs to incorporate into the signature. When ``method`` is set to
            ``detached`` or ``enveloped``, reference URIs are set to this value and only the referenced elements are
            signed.
        :type reference_uri: string or list
        :param key_name: Add a KeyName element in the KeyInfo element that may be used by the signer to communicate a
            key identifier to the recipient. Typically, KeyName contains an identifier related to the key pair used to
            sign the message.
        :type key_name: string
        :param key_info: A custom KeyInfo element to insert in the signature. Use this to supply
            ``<wsse:SecurityTokenReference>`` or other custom key references.
        :type key_info: :py:class:`lxml.etree.Element`
        :param id_attribute:
            Name of the attribute whose value ``URI`` refers to. By default, SignXML will search for "Id", then "ID".
        :type id_attribute: string

        :returns:
            A :py:class:`lxml.etree.Element` object representing the root of the XML tree containing the signature and
            the payload data.

        To specify the location of an enveloped signature within **data**, insert a
        ``<ds:Signature Id="placeholder"></ds:Signature>`` element in **data** (where
        "ds" is the "http://www.w3.org/2000/09/xmldsig#" namespace). This element will
        be replaced by the generated signature, and excised when generating the digest.
        """
        if id_attribute is not None:
            self.id_attributes = (id_attribute, )

        if isinstance(cert, (str, bytes)):
            cert_chain = list(iterate_pem(cert))
        else:
            cert_chain = cert

        if isinstance(reference_uri, (str, bytes)):
            reference_uris = [reference_uri]
        else:
            reference_uris = reference_uri

        sig_root, doc_root, c14n_inputs, reference_uris = self._unpack(data, reference_uris)
        signed_info_element, signature_value_element = self._build_sig(sig_root, reference_uris, c14n_inputs)

        if key is None:
            raise InvalidInput('Parameter "key" is required')

        signed_info_c14n = self._c14n(signed_info_element, algorithm=self.c14n_alg)
        if self.sign_alg.startswith("hmac-"):
            from cryptography.hazmat.primitives.hmac import HMAC
            signer = HMAC(key=key,
                          algorithm=self._get_hmac_digest_method_by_tag(self.sign_alg),
                          backend=default_backend())
            signer.update(signed_info_c14n)
            signature_value_element.text = ensure_str(b64encode(signer.finalize()))
            sig_root.append(signature_value_element)
        elif any(self.sign_alg.startswith(i) for i in ["dsa-", "rsa-", "ecdsa-"]):
            if isinstance(key, (str, bytes)):
                from cryptography.hazmat.primitives.serialization import load_pem_private_key
                key = load_pem_private_key(key, password=passphrase, backend=default_backend())

            hash_alg = self._get_signature_digest_method_by_tag(self.sign_alg)
            if self.sign_alg.startswith("dsa-"):
                signature = key.sign(signed_info_c14n, algorithm=hash_alg)
            elif self.sign_alg.startswith("ecdsa-"):
                signature = key.sign(signed_info_c14n, signature_algorithm=ec.ECDSA(algorithm=hash_alg))
            elif self.sign_alg.startswith("rsa-"):
                signature = key.sign(signed_info_c14n, padding=PKCS1v15(), algorithm=hash_alg)
            else:
                raise NotImplementedError()
            if self.sign_alg.startswith("dsa-"):
                # Note: The output of the DSA signer is a DER-encoded ASN.1 sequence of two DER integers.
                from asn1crypto.algos import DSASignature
                decoded_signature = DSASignature.load(signature).native
                r = decoded_signature['r']
                s = decoded_signature['s']
                signature = long_to_bytes(r).rjust(32, b"\0") + long_to_bytes(s).rjust(32, b"\0")

            signature_value_element.text = ensure_str(b64encode(signature))

            if key_info is None:
                key_info = SubElement(sig_root, ds_tag("KeyInfo"))
                if key_name is not None:
                    keyname = SubElement(key_info, ds_tag("KeyName"))
                    keyname.text = key_name

                if cert_chain is None:
                    self._serialize_key_value(key, key_info)
                else:
                    x509_data = SubElement(key_info, ds_tag("X509Data"))
                    for cert in cert_chain:
                        x509_certificate = SubElement(x509_data, ds_tag("X509Certificate"))
                        if isinstance(cert, (str, bytes)):
                            x509_certificate.text = strip_pem_header(cert)
                        else:
                            from OpenSSL.crypto import dump_certificate, FILETYPE_PEM
                            x509_certificate.text = strip_pem_header(dump_certificate(FILETYPE_PEM, cert))
            else:
                sig_root.append(key_info)
        else:
            raise NotImplementedError()

        if self.method == methods.enveloping:
            for c14n_input in c14n_inputs:
                doc_root.append(c14n_input)
        return doc_root if self.method == methods.enveloped else sig_root
Example #56
0
class Decryptor:
    def __init__(self, rsa_private_key_pem):
        if not isinstance(rsa_private_key_pem, bytes):
            rsa_private_key_pem = rsa_private_key_pem.encode("ascii")
        self.rsa_private_key = serialization.load_pem_private_key(
            data=rsa_private_key_pem,
            password=None,
            backend=default_backend())
        self.cipher = None
        self.authenticator = None
        self._cipher_key_len = None
        self._header_size = None
        self._footer_size = 32

    def expected_header_bytes(self):
        if self._header_size is not None:
            return 0
        return self._cipher_key_len or 8

    def header_size(self):
        return self._header_size

    def footer_size(self):
        return self._footer_size

    def process_header(self, data):
        if self._cipher_key_len is None:
            if data[0:6] != FILEMAGIC:
                raise EncryptorError("Invalid magic bytes")
            self._cipher_key_len = struct.unpack(">H", data[6:8])[0]
        else:
            pad = padding.OAEP(mgf=padding.MGF1(algorithm=SHA1()),
                               algorithm=SHA1(),
                               label=None)
            try:
                plainkey = self.rsa_private_key.decrypt(data, pad)
            except AssertionError:
                raise EncryptorError("Decrypting key data failed")
            if len(plainkey) != 64:
                raise EncryptorError("Integrity check failed")
            key = plainkey[0:16]
            nonce = plainkey[16:32]
            auth_key = plainkey[32:64]
            self._header_size = 8 + len(data)

            self.cipher = Cipher(algorithms.AES(key), modes.CTR(nonce), backend=default_backend()).decryptor()
            self.authenticator = HMAC(auth_key, SHA256(), backend=default_backend())

    def process_data(self, data):
        if not data:
            return b""
        self.authenticator.update(data)
        return self.cipher.update(data)

    def finalize(self, footer):
        if footer != self.authenticator.finalize():
            raise EncryptorError("Integrity check failed")
        result = self.cipher.finalize()
        self.cipher = None
        self.authenticator = None
        return result
Example #57
0
    def sign(self, data, key=None, passphrase=None, cert=None, reference_uri=None, key_name=None):
        """
        Sign the data and return the root element of the resulting XML tree.

        :param data: Data to sign
        :type data: String, file-like object, or XML ElementTree Element API compatible object
        :param key:
            Key to be used for signing. When signing with a certificate or RSA/DSA/ECDSA key, this can be a string
            containing a PEM-formatted key, or a :py:class:`cryptography.hazmat.primitives.interfaces.RSAPublicKey`,
            :py:class:`cryptography.hazmat.primitives.interfaces.DSAPublicKey`, or
            :py:class:`cryptography.hazmat.primitives.interfaces.EllipticCurvePublicKey` object. When signing with a
            HMAC, this should be a string containing the shared secret.
        :type key:
            string, :py:class:`cryptography.hazmat.primitives.interfaces.RSAPublicKey`,
            :py:class:`cryptography.hazmat.primitives.interfaces.DSAPublicKey`, or
            :py:class:`cryptography.hazmat.primitives.interfaces.EllipticCurvePublicKey` object
        :param passphrase: Passphrase to use to decrypt the key, if any.
        :type passphrase: string
        :param cert:
            X.509 certificate to use for signing. This should be a string containing a PEM-formatted certificate, or an
            array of strings or OpenSSL.crypto.X509 objects containing the certificate and a chain of intermediate
            certificates.
        :type cert: string, array of strings, or array of OpenSSL.crypto.X509 objects
        :param reference_uri:
            Custom reference URI to incorporate into the signature. Only used when ``method`` is set to ``detached``.
        :type reference_uri: string
        :param key_name: Add a KeyName element in the KeyInfo element that may be used by the signer to communicate a
            key identifier to the recipient. Typically, KeyName contains an identifier related to the key pair used to
            sign the message.
        :type key_name: string

        :returns:
            A :py:class:`lxml.etree.Element` object representing the root of the XML tree containing the signature and
            the payload data.

        To specify the location of an enveloped signature within **data**, insert a
        `<Signature Id="placeholder"></Signature>` element in **data**. This element will be replaced by the generated
        signature, and excised when generating the digest.
        """
        if isinstance(cert, (str, bytes)):
            cert_chain = [cert]
        else:
            cert_chain = cert

        sig_root, doc_root, c14n_input, reference_uri = self._unpack(data, reference_uri)
        payload_c14n = self._c14n(c14n_input, algorithm=self.c14n_alg)
        digest = self._get_digest(payload_c14n, self._get_digest_method_by_tag(self.digest_alg))
        signed_info_element, signature_value_element = self._build_sig(sig_root, reference_uri, digest)

        signed_info_c14n = self._c14n(signed_info_element, algorithm=self.c14n_alg)
        if self.sign_alg.startswith("hmac-"):
            from cryptography.hazmat.primitives.hmac import HMAC
            signer = HMAC(key=key,
                          algorithm=self._get_hmac_digest_method_by_tag(self.sign_alg),
                          backend=default_backend())
            signer.update(signed_info_c14n)
            signature_value_element.text = ensure_str(b64encode(signer.finalize()))
            sig_root.append(signature_value_element)
        elif any(self.sign_alg.startswith(i) for i in ["dsa-", "rsa-", "ecdsa-"]):
            if isinstance(key, (str, bytes)):
                from cryptography.hazmat.primitives.serialization import load_pem_private_key
                key = load_pem_private_key(key, password=passphrase, backend=default_backend())

            hash_alg = self._get_signature_digest_method_by_tag(self.sign_alg)
            if self.sign_alg.startswith("dsa-"):
                signer = key.signer(signature_algorithm=hash_alg)
            elif self.sign_alg.startswith("ecdsa-"):
                signer = key.signer(signature_algorithm=ec.ECDSA(algorithm=hash_alg))
            elif self.sign_alg.startswith("rsa-"):
                signer = key.signer(padding=PKCS1v15(), algorithm=hash_alg)
            else:
                raise NotImplementedError()
            signer.update(signed_info_c14n)
            signature = signer.finalize()
            if self.sign_alg.startswith("dsa-"):
                # Note: The output of the DSA signer is a DER-encoded ASN.1 sequence of two DER integers.
                decoded_signature = der_decoder.decode(signature)[0]
                r = decoded_signature.getComponentByPosition(0)
                s = decoded_signature.getComponentByPosition(1)
                signature = long_to_bytes(r).rjust(32, b"\0") + long_to_bytes(s).rjust(32, b"\0")

            signature_value_element.text = ensure_str(b64encode(signature))

            key_info = SubElement(sig_root, ds_tag("KeyInfo"))
            if key_name is not None:
                keyname = SubElement(key_info, ds_tag("KeyName"))
                keyname.text = key_name

            if cert_chain is None:
                self._serialize_key_value(key, key_info)
            else:
                x509_data = SubElement(key_info, ds_tag("X509Data"))
                for cert in cert_chain:
                    x509_certificate = SubElement(x509_data, ds_tag("X509Certificate"))
                    if isinstance(cert, (str, bytes)):
                        x509_certificate.text = strip_pem_header(cert)
                    else:
                        from OpenSSL.crypto import dump_certificate, FILETYPE_PEM
                        x509_certificate.text = dump_certificate(FILETYPE_PEM, cert)
        else:
            raise NotImplementedError()

        if self.method == methods.enveloping:
            doc_root.append(c14n_input)
        return doc_root
Example #58
0
    def verify(self, data, require_x509=True, x509_cert=None, ca_pem_file=None, ca_path=None, hmac_key=None,
               validate_schema=True, parser=None, uri_resolver=None, id_attribute=None):
        """
        Verify the XML signature supplied in the data and return the XML node signed by the signature, or raise an
        exception if the signature is not valid. By default, this requires the signature to be generated using a valid
        X.509 certificate. To enable other means of signature validation, set the **require_x509** argument to `False`.

        .. admonition:: See what is signed

         It is important to understand and follow the best practice rule of "See what is signed" when verifying XML
         signatures. The gist of this rule is: if your application neglects to verify that the information it trusts is
         what was actually signed, the attacker can supply a valid signature but point you to malicious data that wasn't
         signed by that signature.

         In SignXML, you can ensure that the information signed is what you expect to be signed by only trusting the
         data returned by the ``verify()`` method. The return value is the XML node or string that was signed. Also,
         depending on the signature settings used, comments in the XML data may not be subject to signing, so may need
         to be untrusted.

         **Recommended reading:** http://www.w3.org/TR/xmldsig-bestpractices/#practices-applications

        TODO: CN verification

        :param data: Signature data to verify
        :type data: String, file-like object, or XML ElementTree Element API compatible object
        :param require_x509:
            If ``True``, a valid X.509 certificate-based signature is required to pass validation. If ``False``, other
            types of valid signatures (e.g. HMAC or RSA public key) are accepted.
        :type require_x509: boolean
        :param x509_cert:
            An external X.509 certificate, given as a PEM-formatted string or OpenSSL.crypto.X509 object, to use for
            verification. Overrides any X.509 certificate information supplied by the signature. If left set to
            ``None``, requires that the signature supply a valid X.509 certificate chain that validates against the
            known certificate authorities. Implies **require_x509=True**.
        :type x509_cert: string or OpenSSL.crypto.X509
        :param ca_pem_file:
            Filename of a PEM file containing certificate authority information to use when verifying certificate-based
            signatures.
        :type ca_pem_file: string or bytes
        :param ca_path:
            Path to a directory containing PEM-formatted certificate authority files to use when verifying
            certificate-based signatures. If neither **ca_pem_file** nor **ca_path** is given, the Mozilla CA bundle
            provided by :py:mod:`certifi` will be loaded.
        :type ca_path: string
        :param hmac_key: If using HMAC, a string containing the shared secret.
        :type hmac_key: string
        :param validate_schema: Whether to validate **data** against the XML Signature schema.
        :type validate_schema: boolean
        :param parser: Custom XML parser instance to use when parsing **data**.
        :type parser: :py:class:`lxml.etree.XMLParser` compatible parser
        :param uri_resolver: Function to use to resolve reference URIs that don't start with "#".
        :type uri_resolver: callable
        :param id_attribute:
            Name of the attribute whose value ``URI`` refers to. By default, SignXML will search for "Id", then "ID".
        :type id_attribute: string

        :raises: :py:class:`cryptography.exceptions.InvalidSignature`

        :returns: VerifyResult object with the signed data, signed xml and signature xml
        :rtype: VerifyResult

        """
        self.hmac_key = hmac_key
        self.require_x509 = require_x509
        self.x509_cert = x509_cert
        self._parser = parser

        if x509_cert:
            self.require_x509 = True

        if id_attribute is None:
            self.id_attributes = ("Id", "ID", "id", "xml:id")
        else:
            self.id_attributes = (id_attribute, )

        root = self.get_root(data)
        if root.tag == ds_tag("Signature"):
            signature_ref = root
        else:
            signature_ref = self._find(root, "Signature", anywhere=True)

        # HACK: deep copy won't keep root's namespaces
        signature = fromstring(etree.tostring(signature_ref), parser=parser)

        if validate_schema:
            self.schema().assertValid(signature)

        signed_info = self._find(signature, "SignedInfo")
        c14n_method = self._find(signed_info, "CanonicalizationMethod")
        c14n_algorithm = c14n_method.get("Algorithm")
        reference = self._find(signed_info, "Reference")
        transforms = self._find(reference, "Transforms", require=False)
        signed_info_c14n = self._c14n(signed_info, algorithm=c14n_algorithm)
        digest_algorithm = self._find(reference, "DigestMethod").get("Algorithm")
        digest_value = self._find(reference, "DigestValue")
        signature_method = self._find(signed_info, "SignatureMethod")
        signature_value = self._find(signature, "SignatureValue")
        signature_alg = signature_method.get("Algorithm")
        raw_signature = b64decode(signature_value.text)
        x509_data = signature.find("ds:KeyInfo/ds:X509Data", namespaces=namespaces)

        if x509_data is not None or self.require_x509:
            from OpenSSL.crypto import load_certificate, X509, FILETYPE_PEM, verify, Error as OpenSSLCryptoError

            if self.x509_cert is None:
                if x509_data is None:
                    raise InvalidInput("Expected a X.509 certificate based signature")
                certs = [cert.text for cert in self._findall(x509_data, "X509Certificate")]
                if not certs:
                    msg = "Expected to find an X509Certificate element in the signature (X509SubjectName, X509SKI are not supported)"  # noqa
                    raise InvalidInput(msg)
                cert_chain = [load_certificate(FILETYPE_PEM, add_pem_header(cert)) for cert in certs]
                verify_x509_cert_chain(cert_chain, ca_pem_file=ca_pem_file, ca_path=ca_path)
            elif isinstance(self.x509_cert, X509):
                cert_chain = [self.x509_cert]
            else:
                cert_chain = [load_certificate(FILETYPE_PEM, add_pem_header(self.x509_cert))]

            signature_digest_method = self._get_signature_digest_method(signature_alg).name
            try:
                verify(cert_chain[-1], raw_signature, signed_info_c14n, signature_digest_method)
            except OpenSSLCryptoError as e:
                try:
                    lib, func, reason = e.message[0]
                except Exception:
                    reason = e
                raise InvalidSignature("Signature verification failed: {}".format(reason))
        elif "hmac-sha" in signature_alg:
            if self.hmac_key is None:
                raise InvalidInput('Parameter "hmac_key" is required when verifying a HMAC signature')

            from cryptography.hazmat.primitives.hmac import HMAC
            signer = HMAC(key=ensure_bytes(self.hmac_key),
                          algorithm=self._get_hmac_digest_method(signature_alg),
                          backend=default_backend())
            signer.update(signed_info_c14n)
            if raw_signature != signer.finalize():
                raise InvalidSignature("Signature mismatch (HMAC)")
        else:
            key_value = signature.find("ds:KeyInfo/ds:KeyValue", namespaces=namespaces)
            if key_value is None:
                raise InvalidInput("Expected to find either KeyValue or X509Data XML element in KeyInfo")

            self._verify_signature_with_pubkey(signed_info_c14n, raw_signature, key_value, signature_alg)

        payload = self._resolve_reference(root, reference, uri_resolver=uri_resolver)
        payload_c14n = self._apply_transforms(payload, transforms, signature_ref, c14n_algorithm)

        if digest_value.text != self._get_digest(payload_c14n, self._get_digest_method(digest_algorithm)):
            raise InvalidDigest("Digest mismatch")

        # We return the signed XML (and only that) to ensure no access to unsigned data happens
        try:
            payload_c14n_xml = fromstring(payload_c14n)
        except etree.XMLSyntaxError:
            payload_c14n_xml = None
        return VerifyResult(payload_c14n, payload_c14n_xml, signature)
Example #59
0
        loads(PeerInfo, object_pairs_hook=OrderedDict), KeyingMode, "", Ns2_b64,
            "", Np2_b64, ""]
MACs2_input = HMAC(Kms2, SHA256(), backend=default_backend())
MACs2_input.update(dumps(MACs2_values['MACs2'], separators=(',', ':')).encode())

# MACp2
MACp2_values = loads('{"MACp2":[]}', object_pairs_hook=OrderedDict)
MACp2_values['MACp2'] = [1, Vers, Verp, PeerId, Cryptosuites, "",
    loads(ServerInfo, object_pairs_hook=OrderedDict), Cryptosuitep, "", Realm,
        loads(PeerInfo, object_pairs_hook=OrderedDict), KeyingMode, "", Ns2_b64,
            "", Np2_b64, ""]
MACp2_input = HMAC(Kmp2, SHA256(), backend=default_backend())
MACp2_input.update(dumps(MACp2_values['MACp2'], separators=(',', ':')).encode())

# MAC - base64 encoded
MACs = base64url_encode(MACs_input.finalize()[:32]).decode().strip('=')
MACp = base64url_encode(MACp_input.finalize()[:32]).decode().strip('=')
MACs2 = base64url_encode(MACs2_input.finalize()[:32]).decode().strip('=')
MACp2 = base64url_encode(MACp2_input.finalize()[:32]).decode().strip('=')

################################################################################
############################## CREATE JSON ARRAYS ##############################
# REQUEST/RESPONSE 1
req1 = loads(
    '{"Type":1, "Vers":"", "PeerId":"", "Realm":"", "Cryptosuites":"",\
        "Dirs":"", "ServerInfo":""}'
    , object_pairs_hook = OrderedDict
)
res1 = loads(
    '{"Type":1, "Verp":"", "PeerId":"", "Cryptosuitep":"", "Dirp":"",\
        "PeerInfo":""}'