def symmetric_key_gen(key, text, mode, algorithm=None):
    backend = default_backend()
    cipher = None
    block_size = 0
    if mode == 'AES':
        block_size = algorithms.AES(key).block_size
        cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=backend)
    elif mode == '3DES':
        block_size = algorithms.TripleDES(key).block_size
        cipher = Cipher(algorithms.TripleDES(key),
                        modes.ECB(),
                        backend=backend)
    elif mode == 'ChaCha20':
        pass
        # block_size=algorithms.ChaCha20(key).block_size
        # cipher=Cipher(algorithms.ChaCha20(key),modes.ECB(),backend=backend)
    else:
        raise Exception("Mode not found")

    encryptor = cipher.encryptor()
    padding = block_size - len(text) % block_size
    padding = 16 if padding == 0 else padding
    text += bytes([padding] * padding)
    ct = encryptor.update(text)
    return ct
Exemple #2
0
def DESL(key, digest):
    """DESL encrypts a response key and digest and returns a challenge response

    Args:
        key (bytes): a NT or LM response key
        digest (bytes): a Server, Client or Server+Client challenge
    Returns:
        bytes: a NT or LM ChallengeResponse
    """
    des_key = _create_des_key(key[0:7])
    cipher = Cipher(
        algorithms.TripleDES(des_key), modes.ECB(), backend=default_backend()
    )
    encryptor = cipher.encryptor()
    res = encryptor.update(digest) + encryptor.finalize()

    des_key = _create_des_key(key[7:14])
    cipher = Cipher(
        algorithms.TripleDES(des_key), modes.ECB(), backend=default_backend()
    )
    encryptor = cipher.encryptor()
    res += encryptor.update(digest) + encryptor.finalize()

    des_key = _create_des_key(key[14:16] + b"\0" * 5)
    cipher = Cipher(
        algorithms.TripleDES(des_key), modes.ECB(), backend=default_backend()
    )
    encryptor = cipher.encryptor()
    res += encryptor.update(digest) + encryptor.finalize()

    return res
    def decryption(self, data,iv=None,tag=None,nonce=None):
        backend = default_backend() 
        cipher = None
        block_size = 0

        if self.symmetric_cipher!='ChaCha20':
            if self.cipher_mode == 'ECB':
                mode = modes.ECB()
            elif self.cipher_mode == 'GCM':
                mode = modes.GCM(iv,tag)
            elif self.cipher_mode == 'CBC':
                if iv is not None:
                    mode = modes.CBC(iv)

        if self.symmetric_cipher == 'AES':
            block_size = algorithms.AES(self.symmetric_key).block_size
            cipher = Cipher(algorithms.AES(self.symmetric_key), mode, backend=backend)
        elif self.symmetric_cipher == '3DES':
            block_size = algorithms.TripleDES(self.symmetric_key).block_size
            cipher = Cipher(algorithms.TripleDES(self.symmetric_key), mode, backend=backend)
        elif self.symmetric_cipher == 'ChaCha20':
            algorithm = algorithms.ChaCha20(self.symmetric_key, nonce)
            cipher = Cipher(algorithm, mode=None, backend=default_backend())
        else:
            raise Exception("Mode not found")
            
        decryptor = cipher.decryptor()

        ct = decryptor.update(data)+decryptor.finalize()
        
        if self.cipher_mode=='GCM' or self.symmetric_cipher=='ChaCha20':
            return ct
        return ct[:-ct[-1]]
class TestTripleDESModeCBC(object):
    test_kat = generate_encrypt_test(
        load_nist_vectors,
        os.path.join("ciphers", "3DES", "CBC"),
        [
            "TCBCinvperm.rsp",
            "TCBCpermop.rsp",
            "TCBCsubtab.rsp",
            "TCBCvarkey.rsp",
            "TCBCvartext.rsp",
        ],
        lambda keys, **kwargs: algorithms.TripleDES(binascii.unhexlify(keys)),
        lambda iv, **kwargs: modes.CBC(binascii.unhexlify(iv)),
    )

    test_mmt = generate_encrypt_test(
        load_nist_vectors,
        os.path.join("ciphers", "3DES", "CBC"),
        [
            "TCBCMMT1.rsp",
            "TCBCMMT2.rsp",
            "TCBCMMT3.rsp",
        ],
        lambda key1, key2, key3, **kwargs: algorithms.TripleDES(
            binascii.unhexlify(key1 + key2 + key3)),
        lambda iv, **kwargs: modes.CBC(binascii.unhexlify(iv)),
    )
Exemple #5
0
def calc_des(data, key, ifenc=True, mode='ECB', iv=None):
    if isinstance(data, str):
        data = bytes.fromhex(data)
    if isinstance(key, str):
        key = bytes.fromhex(key)
    if isinstance(iv, str):
        iv = bytes.fromhex(iv)

    backend = default_backend()
    if mode == 'ECB':
        cipher = Cipher(algorithms.TripleDES(key),
                        modes.ECB(),
                        backend=backend)
    else:
        cipher = Cipher(algorithms.TripleDES(key),
                        modes.CBC(iv),
                        backend=backend)
    if ifenc:
        encryptor = cipher.encryptor()
        ct = encryptor.update(data) + encryptor.finalize()
        return ct
    else:
        decryptor = cipher.decryptor()
        ct = decryptor.update(data) + decryptor.finalize()
        return ct
class TestTripleDESModeOFB(object):
    test_KAT = generate_encrypt_test(
        load_nist_vectors,
        os.path.join("ciphers", "3DES", "OFB"),
        [
            "TOFBpermop.rsp",
            "TOFBsubtab.rsp",
            "TOFBvarkey.rsp",
            "TOFBvartext.rsp",
            "TOFBinvperm.rsp",
        ],
        lambda keys, **kwargs: algorithms.TripleDES(binascii.unhexlify(keys)),
        lambda iv, **kwargs: modes.OFB(binascii.unhexlify(iv)),
    )

    test_MMT = generate_encrypt_test(
        load_nist_vectors,
        os.path.join("ciphers", "3DES", "OFB"),
        [
            "TOFBMMT1.rsp",
            "TOFBMMT2.rsp",
            "TOFBMMT3.rsp",
        ],
        lambda key1, key2, key3, **kwargs: algorithms.TripleDES(
            binascii.unhexlify(key1 + key2 + key3)
        ),
        lambda iv, **kwargs: modes.OFB(binascii.unhexlify(iv)),
    )
Exemple #7
0
    def file_encryption(self, data):
        backend = default_backend()
        cipher = None
        block_size = 0
        mode = None

        if self.symmetric_cipher != 'ChaCha20':
            if self.cipher_mode == 'ECB':
                mode = modes.ECB()
            elif self.cipher_mode == 'GCM':
                self.iv = os.urandom(16)
                mode = modes.GCM(self.iv)
            elif self.cipher_mode == 'CBC':
                if self.symmetric_cipher == '3DES':
                    self.iv = os.urandom(8)
                elif self.symmetric_cipher == 'AES':
                    self.iv = os.urandom(16)
                mode = modes.CBC(self.iv)

        if self.symmetric_cipher == 'AES':
            block_size = algorithms.AES(self.symmetric_key).block_size
            cipher = Cipher(algorithms.AES(self.symmetric_key),
                            mode,
                            backend=backend)

        elif self.symmetric_cipher == '3DES':
            block_size = algorithms.TripleDES(self.symmetric_key).block_size
            cipher = Cipher(algorithms.TripleDES(self.symmetric_key),
                            mode,
                            backend=backend)

        elif self.symmetric_cipher == 'ChaCha20':
            nonce = os.urandom(16)
            algorithm = algorithms.ChaCha20(self.symmetric_key, nonce)
            cipher = Cipher(algorithm, mode=None, backend=default_backend())
        else:
            raise Exception("Symmetric cipher not found")

        encryptor = cipher.encryptor()

        if self.cipher_mode != 'GCM' and self.symmetric_cipher != 'ChaCha20':
            padding = block_size - len(data) % block_size

            padding = 16 if padding and self.symmetric_cipher == 'AES' == 0 else padding
            padding = 8 if padding and self.symmetric_cipher == '3DES' == 0 else padding

            data += bytes([padding] * padding)
            criptogram = encryptor.update(data)
        elif self.symmetric_cipher == 'ChaCha20':

            criptogram = encryptor.update(data)
            self.nonce = nonce
        else:
            criptogram = encryptor.update(data) + encryptor.finalize()
            self.gcm_tag = encryptor.tag

        return criptogram
    def auth_ultralight_c(self, key=DEFAULT_KEY):
        self.reader.mfrc522_request(self.reader.PICC_REQA)
        uid1 = self.reader.mfrc522_anticol1()
        self.reader.mfrc522_select_tag1(uid1)
        uid2 = self.reader.mfrc522_anticol2()
        self.reader.mfrc522_select_tag2(uid2)

        uid = bytes(uid1[1:4] + uid2[:4])

        (backData,
         backLen) = self.reader.mfrc522_transeive_helper([0x1A, 0x00])
        print(backData)
        if backData[0] != 0xAF:
            raise AuthError("invalid auth response")

        ct = bytes(backData[1:9])

        cipher = Cipher(
            algorithms.TripleDES(key),
            mode=modes.CBC(INITIAL_IV),
            backend=default_backend(),
        )
        decryptor = cipher.decryptor()

        rand_b = decryptor.update(ct) + decryptor.finalize()
        rand_a = token_bytes(8)

        cipher2 = Cipher(algorithms.TripleDES(key),
                         mode=modes.CBC(ct),
                         backend=default_backend())
        encryptor = cipher2.encryptor()
        response = (encryptor.update(rand_a + rand_b[1:] + rand_b[:1]) +
                    encryptor.finalize())
        assert len(response) == 16, "Response should be 16 bytes"
        (backData,
         backLen) = self.reader.mfrc522_transeive_helper([0xAF, *response])
        print(backData)
        if backData[0] != 0x00:
            raise AuthError("invalid auth response")

        ct2 = bytes(backData[1:9])
        cipher3 = Cipher(
            algorithms.TripleDES(key),
            mode=modes.CBC(response[8:]),
            backend=default_backend(),
        )
        decryptor2 = cipher3.decryptor()
        rand_a_prime = decryptor2.update(ct2) + decryptor2.finalize()

        if rand_a_prime[-1:] + rand_a_prime[:-1] != rand_a:
            raise AuthError("randA did not match")

        return uid
    def test_cmac(self):
        backend = MultiBackend([DummyCMACBackend([algorithms.AES])])

        fake_key = b"\x00" * 16

        assert backend.cmac_algorithm_supported(algorithms.AES(fake_key))
        assert not backend.cmac_algorithm_supported(
            algorithms.TripleDES(fake_key))

        cmac.CMAC(algorithms.AES(fake_key), backend)

        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_CIPHER):
            cmac.CMAC(algorithms.TripleDES(fake_key), backend)
Exemple #10
0
 def basic_decrypt(cls, key, ciphertext):
     assert len(ciphertext) % 8 == 0
     algo = ciphers.TripleDES(key.contents)
     cbc = modes.CBC(bytes(8))
     decryptor = Cipher(algo, cbc, default_backend()).decryptor()
     plaintext = decryptor.update(ciphertext)
     return plaintext
Exemple #11
0
 def basic_encrypt(cls, key, plaintext):
     assert len(plaintext) % 8 == 0
     algo = ciphers.TripleDES(key.contents)
     cbc = modes.CBC(bytes(8))
     encryptor = Cipher(algo, cbc, default_backend()).encryptor()
     ciphertext = encryptor.update(plaintext)
     return ciphertext
Exemple #12
0
    def decrypt_message(self, cryptogram, iv, key):
        """Decrypts messages with a symmetric key"""

        cipher = None
        algorithm = None
        mode = None
        enc_shared_key = key[len(key) // 2:]
        if self.cipher == 'AES':
            algorithm = algorithms.AES(enc_shared_key)
        elif self.cipher == '3DES':
            algorithm = algorithms.TripleDES(enc_shared_key)
        elif self.cipher == 'ChaCha20':
            # in this case the nonce is the iv
            if iv != None:
                algorithm = algorithms.ChaCha20(enc_shared_key, iv)
        else:
            logger.debug('Algorithm not suported')

        # with ChaCha20 we do not pad the data
        if self.ciphermode == 'CBC':
            mode = modes.CBC(iv)
        elif self.ciphermode == 'CTR':
            mode = modes.CTR(iv)

        cipher = Cipher(algorithm, mode=mode)
        decryptor = cipher.decryptor()
        if self.cipher == 'ChaCha20':
            return decryptor.update(cryptogram) + decryptor.finalize()
        else:
            padded_data = decryptor.update(cryptogram) + decryptor.finalize()
            unpadder = padding.PKCS7(algorithm.block_size).unpadder()
            text = unpadder.update(padded_data)
            text += unpadder.finalize()
            return text
Exemple #13
0
    def encrypt_message(self, text, key):
        """Encrypts message with a symmetric key"""
        iv = os.urandom(16)
        cipher = None
        algorithm, iv = None, None
        mode = None

        enc_shared_key = key[len(key) // 2:]

        if self.cipher == 'AES':
            algorithm = algorithms.AES(enc_shared_key)
        elif self.cipher == '3DES':
            algorithm = algorithms.TripleDES(enc_shared_key)
        else:
            iv = os.urandom(16)
            algorithm = algorithms.ChaCha20(enc_shared_key, iv)
            logger.error('Algorithm not suported')

        if self.cipher != 'ChaCha20':
            # with ChaCha20 we do not pad the data
            iv = os.urandom(algorithm.block_size // 8)
            if self.ciphermode == 'CBC':
                mode = modes.CBC(iv)
            elif self.ciphermode == 'CTR':
                mode = modes.CTR(iv)
            padder = padding.PKCS7(algorithm.block_size).padder()
            padded_data = padder.update(text)
            padded_data += padder.finalize()
            text = padded_data
        cipher = Cipher(algorithm, mode=mode)
        encryptor = cipher.encryptor()
        cryptogram = encryptor.update(text) + encryptor.finalize()

        return cryptogram, iv
Exemple #14
0
 def update(self, chunk):
     if self._cipher is None:
         if len(chunk) < 16:
             raise Exception('Invalid first chunk (Size < 16).')
         if chunk[0:8] != b"Salted__":
             raise Exception('Invalid first chunk (expected: Salted__')
         [key, iv] = self._get_key_iv(self._password, chunk[8:16])
         if HAS_M2CRYPTO:
             self._cipher = EVP.Cipher('des_cbc', key, iv, 0)
         elif HAS_CRYPTOGRAPHY:
             self._cipher = Cipher(algorithms.TripleDES(key),
                                   modes.CBC(iv),
                                   backend=default_backend()).decryptor()
         else:
             self._cipher = DES.new(key, DES.MODE_CBC, iv)
         chunk = chunk[16:]
     if len(chunk) > 0:
         if HAS_M2CRYPTO:
             return self._cipher.update(chunk)
         elif HAS_CRYPTOGRAPHY:
             return self._cipher.update(chunk)
         else:
             return self._cipher.decrypt(chunk)
     else:
         return b""
Exemple #15
0
    def decrypt_simple(self, username):
        """Decrypt a credential using the simple approach. It only handles 3DES.
        Tries to parse the decrypted object into a plain credential object type. If it fails,
        probably due to an invalid username use to decrypt it, raises an exception.

        :param username: Username to use when decrypting
        :type username: string

        :return: decrypted object
        :rtype: SAPCredv2_Cred_Plain
        """

        blob = self.cipher.val_readable

        # Construct the key using the key format and the username
        key = (cred_key_fmt % username)[:24]
        # Set empty IV
        iv = "\x00" * 8

        # Decrypt the cipher text with the derived key and IV
        decryptor = Cipher(algorithms.TripleDES(key),
                           modes.CBC(iv),
                           backend=default_backend()).decryptor()
        plain = decryptor.update(blob) + decryptor.finalize()

        return SAPCredv2_Cred_Plain(plain)
Exemple #16
0
    def authenticate(self, key, touch_callback=None):
        ct1 = self.send_cmd(INS.AUTHENTICATE, ALGO.TDES, SLOT.CARD_MANAGEMENT,
                            Tlv(TAG.DYN_AUTH, Tlv(0x80)))[4:12]
        backend = default_backend()
        cipher = Cipher(algorithms.TripleDES(key), modes.ECB(), backend)
        decryptor = cipher.decryptor()
        pt1 = decryptor.update(ct1) + decryptor.finalize()
        ct2 = os.urandom(8)

        if touch_callback is not None:
            touch_timer = Timer(0.500, touch_callback)
            touch_timer.start()

        try:
            pt2 = self.send_cmd(
                INS.AUTHENTICATE, ALGO.TDES, SLOT.CARD_MANAGEMENT,
                Tlv(TAG.DYN_AUTH, Tlv(0x80, pt1) + Tlv(0x81, ct2))
                )[4:12]
        finally:
            if touch_callback is not None:
                touch_timer.cancel()

        encryptor = cipher.encryptor()
        pt2_cmp = encryptor.update(ct2) + encryptor.finalize()
        if not bytes_eq(pt2, pt2_cmp):
            raise ValueError('Device challenge did not match!')
        self._authenticated = True
Exemple #17
0
    def __init__(self,
                 cipher_mode=None,
                 initialization_vector=None,
                 key=None,
                 **kwargs):
        """Initializes a decrypter.

    Args:
      cipher_mode (Optional[str]): cipher mode.
      initialization_vector (Optional[bytes]): initialization vector.
      key (Optional[bytes]): key.
      kwargs (dict): keyword arguments depending on the decrypter.

    Raises:
      ValueError: when key is not set or the cipher mode is not supported.
    """
        if not key:
            raise ValueError('Missing key.')

        if cipher_mode not in self._ENCRYPTION_MODES:
            raise ValueError(
                'Unsupported cipher mode: {0!s}'.format(cipher_mode))

        algorithm = algorithms.TripleDES(key)

        super(DES3Decrypter,
              self).__init__(algorithm=algorithm,
                             cipher_mode=cipher_mode,
                             initialization_vector=initialization_vector,
                             **kwargs)
Exemple #18
0
 def _new_cipher(key):
     skey = key[0:
                crypto_algo["key_size"]]  # Use first n bytes as crypto key
     iv = key[-crypto_algo["iv_size"]:]  # Use last m bytes as IV
     return Cipher(algorithms.TripleDES(skey),
                   modes.CBC(iv),
                   backend=default_backend())
Exemple #19
0
def TripleDES():
    backend = default_backend()
    key = os.urandom(16)
    iv = os.urandom(8)
    
    user_input = input('Please enter a message: ')
    
    cipher = Cipher(algorithms.TripleDES(key), modes.OFB(iv), backend=default_backend())
    encryptor = cipher.encryptor()
    user_input_byt = str.encode(user_input)
    ct = encryptor.update(user_input_byt) + encryptor.finalize()
    
    print('The 3DES key is {}'.format(ct))
    
    decryptor = cipher.decryptor()
    answer = decryptor.update(ct) + decryptor.finalize()
    print('The decrypted message: {}'.format(answer))
    
    a = input('Would you like to know more about 3DES? (yes/no) ')
    if a == 'yes':
        print('Triple DES (Data Encryption Standard), sometimes referred to as 3DES, is a block cipher standardized by NIST. Triple DES has known crypto-analytic flaws, however none of them currently enable a practical attack. Nonetheless, Triple DES is not recommended for new applications because it is incredibly slow; old applications should consider moving away from it.')
        print('   ')
        print('For this 3DES implenebtation, it uses OFB Mode. OFB (Output Feedback) is a mode of operation for block ciphers. It transforms a block cipher into a stream cipher.')
        print('   ')
        print('Becase it is a stream cipher, it does not need padding.')
        print('   ')
        print('iv = initialization_vector (bytes) – Must be random bytes. They do not need to be kept secret and they can be included in a transmitted message. Must be the same number of bytes as the block_size of the cipher. Do not reuse an initialization_vector with a given key.')
        print('   ')
        print('key (bytes) – The secret key. This must be kept secret.')
    elif a == 'no':
            print('That\'s great.')
Exemple #20
0
  def testInitialize(self):
    """Tests the __init__ method."""
    algorithm = algorithms.TripleDES(self._DES3_KEY)

    test_decrypter = decrypter.CryptographyBlockCipherDecrypter(
        algorithm=algorithm, cipher_mode=definitions.ENCRYPTION_MODE_CBC,
        initialization_vector=self._DES3_INITIALIZATION_VECTOR)
    self.assertIsNotNone(test_decrypter)

    test_decrypter = decrypter.CryptographyBlockCipherDecrypter(
        algorithm=algorithm, cipher_mode=definitions.ENCRYPTION_MODE_CFB,
        initialization_vector=self._DES3_INITIALIZATION_VECTOR)
    self.assertIsNotNone(test_decrypter)

    test_decrypter = decrypter.CryptographyBlockCipherDecrypter(
        algorithm=algorithm, cipher_mode=definitions.ENCRYPTION_MODE_ECB)
    self.assertIsNotNone(test_decrypter)

    test_decrypter = decrypter.CryptographyBlockCipherDecrypter(
        algorithm=algorithm, cipher_mode=definitions.ENCRYPTION_MODE_OFB,
        initialization_vector=self._DES3_INITIALIZATION_VECTOR)
    self.assertIsNotNone(test_decrypter)

    with self.assertRaises(ValueError):
      decrypter.CryptographyBlockCipherDecrypter(
          algorithm=algorithm, cipher_mode=definitions.ENCRYPTION_MODE_CBC)
Exemple #21
0
 def setup_cipher(self):
     algorithm = algorithms.TripleDES(self.key)
     self._cipher = Cipher(algorithm,
                           mode=self.IV,
                           backend=default_backend())
     self.encryptor = self._cipher.encryptor()
     self.decryptor = self._cipher.decryptor()
Exemple #22
0
def encode_text(text: AnyStr, key: AnyStr) -> bytes:
    """Encode text using triple DES and ECB mode.

    .. code-block:: python

        # output: b'OdiOLVWUv7f8OzfNsuB5Fg=='
        encode_text("secret text", "a" * 24)

    :params text: Plain text (``str`` or ``bytes``) need to be encoded.
    :params key: Key used for encoding salt.
    :returns: Encoded ``bytes`` text.
    """
    with contextlib.suppress(AttributeError):
        # ``key`` must be a ``bytes``
        key = key.encode()

    with contextlib.suppress(AttributeError):
        # ``text`` must be a ``bytes``
        text = text.encode()

    cipher = Cipher(
        algorithms.TripleDES(key), modes.ECB(), backend=default_backend(),
    )
    encryptor = cipher.encryptor()

    padder = padding.PKCS7(algorithms.TripleDES.block_size).padder()
    padded_data = padder.update(text) + padder.finalize()

    encrypted_text = encryptor.update(padded_data) + encryptor.finalize()
    return base64.b64encode(encrypted_text)
Exemple #23
0
def encrypt_tdes_cbc(key: bytes, iv: bytes, data: bytes) -> bytes:
    r"""Encrypt data using Triple DES CBC algorithm.

    Parameters
    ----------
    key : bytes
        Binary Triple DES key. Has to be a valid DES key.
    iv : bytes
        Binary initial initialization vector for CBC.
    data : bytes
        Binary data to be encrypted.

    Returns
    -------
    encrypted_data : bytes
        Binary encrypted data.

    Examples
    --------
    >>> from pyemv.tools import encrypt_tdes_cbc
    >>> key = bytes.fromhex("0123456789ABCDEFFEDCBA9876543210")
    >>> iv = bytes.fromhex("0000000000000000")
    >>> encrypt_tdes_cbc(key, iv, b"12345678").hex().upper()
    '41D2FFBA3CDC15FE'
    """
    cipher = _Cipher(
        _algorithms.TripleDES(key),
        _modes.CBC(iv),
        backend=_default_backend(),
    )
    return cipher.encryptor().update(data)
Exemple #24
0
def key_check_digits(key: bytes, length: int = 2) -> bytes:
    r"""Calculate Triple DES key check digits.

    Parameters
    ----------
    key : bytes
        Binary key to provide check digits for. Has to be a valid DES key.
    length : int, optional
        Number of key check digits bytes provided in the response (default 2).

    Returns
    -------
    check_digits : bytes
        Binary check digits (`length` bytes)

    Examples
    --------
    >>> from pyemv import tools
    >>> key = bytes.fromhex("0123456789ABCDEFFEDCBA9876543210")
    >>> tools.key_check_digits(key).hex().upper()
    '08D7'
    """
    cipher = _Cipher(_algorithms.TripleDES(key),
                     _modes.ECB(),
                     backend=_default_backend())
    encryptor = cipher.encryptor()
    return encryptor.update(b"\x00\x00\x00\x00\x00\x00\x00\x00")[:length]
Exemple #25
0
def decode_text(text: AnyStr, key: AnyStr) -> bytes:
    """Decode text using triple DES and ECB mode.

    .. code-block:: python

        # output: b'secret text'
        decode_text(b'OdiOLVWUv7f8OzfNsuB5Fg==', "a" * 24)

    :params text: Encoded text (``str`` or ``bytes``) need to be decoded.
    :params key: Key used for decoding salt.
    :returns: Decoded ``bytes`` text.
    """
    encoded_text = base64.b64decode(text)

    with contextlib.suppress(AttributeError):
        # ``key`` must be a ``bytes``
        key = key.encode()

    cipher = Cipher(
        algorithms.TripleDES(key), modes.ECB(), backend=default_backend(),
    )
    decryptor = cipher.decryptor()

    unpadder = padding.PKCS7(algorithms.TripleDES.block_size).unpadder()
    padded_data = decryptor.update(encoded_text) + decryptor.finalize()

    # decrypt the encrypted text
    return unpadder.update(padded_data) + unpadder.finalize()
Exemple #26
0
def generate_kcv(key: bytes, length: int = 2) -> bytes:
    r"""Generate DES key checksum value (KCV).

    Parameters
    ----------
    key : bytes
        Binary key to provide check digits for. Has to be a valid DES key.
    length : int, optional
        Number of KCV bytes returned (default 2).

    Returns
    -------
    kcv : bytes
        Binary KCV (`length` bytes)

    Examples
    --------
    >>> import psec
    >>> key = bytes.fromhex("0123456789ABCDEFFEDCBA9876543210")
    >>> psec.des.generate_kcv(key).hex().upper()
    '08D7'
    """
    cipher = _Cipher(_algorithms.TripleDES(key),
                     _modes.ECB(),
                     backend=_default_backend())
    encryptor = cipher.encryptor()
    return encryptor.update(b"\x00\x00\x00\x00\x00\x00\x00\x00")[:length]
Exemple #27
0
def encrypt_tdes_ecb(key: bytes, data: bytes) -> bytes:
    r"""Encrypt data using Triple DES ECB algorithm.

    Parameters
    ----------
    key : bytes
        Binary Triple DES key. Has to be a valid DES key.
    data : bytes
        Binary data to be encrypted.

    Returns
    -------
    encrypted_data : bytes
        Binary encrypted data.

    Examples
    --------
    >>> from pyemv.tools import encrypt_tdes_ecb
    >>> key = bytes.fromhex("0123456789ABCDEFFEDCBA9876543210")
    >>> encrypt_tdes_ecb(key, b"12345678").hex().upper()
    '41D2FFBA3CDC15FE'
    """
    cipher = _Cipher(_algorithms.TripleDES(key),
                     _modes.ECB(),
                     backend=_default_backend())
    return cipher.encryptor().update(data)
Exemple #28
0
def pyca_tests():
    from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
    from cryptography.hazmat.primitives.asymmetric import rsa, padding

    Cipher(
        algorithms.TripleDES(key),
        modes.CBC(iv))  # Noncompliant {{Use secure mode and padding scheme.}}
    #                                   ^^^^^^^^^^^^^
    Cipher(algorithms.Blowfish(key), modes.GCM(iv))  # Compliant
    Cipher()  # Compliant
    args = []
    Cipher(algorithms.Blowfish(key), *args)  # Compliant
    Cipher(algorithms.Blowfish(key), modes.ECB())  # Noncompliant
    Cipher(algorithms.AES(key), modes.CBC(iv))  # Noncompliant
    Cipher(mode=modes.CBC(iv), algorithm=algorithms.AES(key))  # Noncompliant
    Cipher(algorithms.AES(key), modes.OFB(iv))  # Compliant
    Cipher(algorithms.AES(key), modes.ECB())  # Noncompliant

    private_key = rsa.generate_private_key()
    public_key = private_key.public_key()
    ciphertext = public_key.encrypt(message, padding.OAEP())

    private_key.decrypt(ciphertext, padding.OAEP())  # Compliant
    public_key.encrypt(message, padding.PKCS1v15())  # Noncompliant
    #                             ^^^^^^^^^^^^^^^^^^
    public_key.encrypt(padding=padding.PKCS1v15(),
                       plaintext=message)  # Noncompliant
    private_key.decrypt(ciphertext, padding.PKCS1v15())  # Noncompliant
    private_key.decrypt(padding=padding.PKCS1v15(),
                        ciphertext=ciphertext)  # Noncompliant
    print(padding.PKCS1v15())  # OK
Exemple #29
0
def get_cipher(ciphername, derived_key):
    
    info = _cipher_info.get(ciphername)
    if info is None:
        raise ValueError(f'Unsupported cipher: {ciphername}')

    ivlen, keylen = info
    assert( len(derived_key) == sum(info) )
    key = derived_key[:keylen]
    iv = derived_key[keylen:]

    LOG.debug('Decryptiong Key (%d): %s', len(key), key.hex().upper())
    LOG.debug('IV (%d): %s', len(iv), iv.hex().upper())

    backend = default_backend()

    if ciphername in (b"aes128-ctr", b"aes192-ctr", b"aes256-ctr"):
        return Cipher(algorithms.AES(key), modes.CTR(iv), backend=backend)

    # if ciphername == b"blowfish-cbc":
    #     return Cipher(algorithms.Blowfish(key), modes.CBC(iv), backend=backend)

    if ciphername in (b"aes128-cbc", b"aes192-cbc", b"aes256-cbc"):
        return Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend)

    if ciphername == b"3des-cbc":
        return Cipher(algorithms.TripleDES(key), modes.CBC(iv), backend=backend)
    
    # Should not come here
    raise ValueError(f'Unsupported cipher: {ciphername}')
    def test_ciphers(self):
        backend = MultiBackend([
            DummyHashBackend([]),
            DummyCipherBackend([
                (algorithms.AES, modes.CBC),
            ])
        ])
        assert backend.cipher_supported(
            algorithms.AES(b"\x00" * 16), modes.CBC(b"\x00" * 16)
        )
        assert not backend.cipher_supported(
            algorithms.TripleDES(b"\x00" * 16), modes.CBC(b"\x00" * 16)
        )

        cipher = Cipher(
            algorithms.AES(b"\x00" * 16),
            modes.CBC(b"\x00" * 16),
            backend=backend
        )
        cipher.encryptor()
        cipher.decryptor()

        cipher = Cipher(
            algorithms.Camellia(b"\x00" * 16),
            modes.CBC(b"\x00" * 16),
            backend=backend
        )
        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_CIPHER):
            cipher.encryptor()
        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_CIPHER):
            cipher.decryptor()