Example #1
0
def decode(data, key, mode, iv):
    ## Do the real decoding here
    key = key.encode()
    iv = iv.encode()
    block_size = 16

    if mode == 'ecb':
        decryption_suite = AES.new(key, AES.MODE_ECB)
        dec_data = decryption_suite.decrypt(data)
        dec_data = unpad(dec_data, block_size, style='pkcs7')
    elif mode == 'cbc':
        decryption_suite = AES.new(key, AES.MODE_CBC, iv)
        dec_data = decryption_suite.decrypt(data)
        dec_data = unpad(dec_data, block_size, style='pkcs7')
    elif mode == 'cfb':
        decryption_suite = AES.new(key, AES.MODE_CFB, iv)
        dec_data = decryption_suite.decrypt(data)
    elif mode == 'ofb':
        decryption_suite = AES.new(key, AES.MODE_OFB, iv)
        dec_data = decryption_suite.decrypt(data)

    #dec_data = unpad(dec_data, block_size, style='pkcs7')

    #dec_data = "This is a decoded text giving you the original" #used for testing only
    return dec_data
Example #2
0
 def run(self):
     assert self.outA is not None
     assert self.outB is not None
     self.p, g = self.inA.get()
     # picking an attack at random
     attack = randint(0, 2)
     (self.attack1, self.attack2, self.attack3)[attack]()
     print('Eve:   key', self.key.hex())
     ciph, iv = self.inA.get()
     try:
         msg = unpad(AES.new(self.key, AES.MODE_CBC, iv).decrypt(ciph), BS)
     except ValueError:
         # see comments in attack3() code below
         assert attack == 2
         print(
             'Eve:   probabilistic attack FAILED, switching to ACTIVE attack'
         )
         self.attack3_active(ciph, iv)
         return
     print('Eve:  ', msg)
     self.outB.put((ciph, iv))
     ciph, iv = self.inB.get()
     self.outA.put((ciph, iv))
     msg = unpad(AES.new(self.key, AES.MODE_CBC, iv).decrypt(ciph), BS)
     print('Eve:  ', msg)
     print('Eve:   done')
Example #3
0
 def oracle(iv, ciphertext):
     cipher = AES.new(key, AES.MODE_CBC, iv=iv)
     plaintext = cipher.decrypt(ciphertext)
     try:
         unpad(plaintext, AES.block_size)
         return True
     except:
         return False
Example #4
0
    def decrypt(login, password, salt):
        key = hashlib.scrypt(programm_password.encode(), salt=salt, n=2**14, r=8, p=1, dklen=32)
        cipher = AES.new(key, AES.MODE_CBC, salt)
        try:
            login = unpad(cipher.decrypt(login), 32)
            password = unpad(cipher.decrypt(password), 32)
            return str(login,encoding='utf-8'), str(password,encoding='utf-8')

        except ValueError:
            messagebox.showerror("Error!", "wrong password!")
            return "*******", "*******"
Example #5
0
 def attack3_active(self, ciphA, ivA):
     sA = self.p - self.s
     keyA = SHA1.new(int_to_bytes(sA)).digest()[:BS]
     print("Eve:   Alice's key", keyA.hex())
     msg = unpad(AES.new(keyA, AES.MODE_CBC, ivA).decrypt(ciphA), BS)
     print('Eve:  ', msg)
     ciph = AES.new(self.key, AES.MODE_CBC, ivA).encrypt(pad(msg, BS))
     self.outB.put((ciph, ivA))
     ciph, iv = self.inB.get()
     msg = unpad(AES.new(self.key, AES.MODE_CBC, iv).decrypt(ciph), BS)
     print('Eve:  ', msg)
     ciphA = AES.new(keyA, AES.MODE_CBC, iv).encrypt(pad(msg, BS))
     self.outA.put((ciphA, iv))
     print('Eve:   done')
Example #6
0
def decrypt(mensaje):
    """
        Nombre: decrypt
        Descripcion: Funcion que descifra un mensaje.
        Argumentos:
            -mensaje: mensaje cifrado y firmado
        Retorno: mensaje descifrado
    """
    # Obtenemos el vector de inicializacion y el sobre digital
    print("-> Descifrando fichero...", end="")
    iv = mensaje[0:16]
    sobre_digital = mensaje[16:16 + 256]

    # Obtenemos la clave privada del receptor
    f = open('clave.pem', 'r')
    clave_priv_r = RSA.import_key(f.read())
    f.close()

    # Obtenemos el sobre con OAEP
    cipher = PKCS1_OAEP.new(clave_priv_r)
    try:
        clave_s = cipher.decrypt(sobre_digital)
    except ValueError:
        print("Error: No es posible descifrar")
        return None

    # Desciframos y quitamos el pad
    cipher = AES.new(clave_s, AES.MODE_CBC, iv)
    mensaje_descifrado = unpad(cipher.decrypt(mensaje[16 + 256:]),
                               AES.block_size)

    print("OK")
    return mensaje_descifrado
Example #7
0
    def parse(self, data: (bytes, bytearray)) -> (bytes, bytearray):
        global REQUEST_PRV_KEY

        self.enc_output = data

        iv = data[:16]

        cipher = AES.new(REQUEST_SECRET, AES.MODE_CBC, iv)
        enc_data = data[16:]  # array + signature
        dec_data = unpad(cipher.decrypt(enc_data), AES.block_size)

        body = dec_data[:
                        -REQUEST_PRV_KEY.size_in_bytes()]  # UNIQUE_MAGIC + DNA
        self.signature = dec_data[-REQUEST_PRV_KEY.size_in_bytes():]

        # verify file magic
        assert body[:4] == REQUEST_MAGIC, "Invalid update request magic"

        # verify signature
        verifier = PKCS1_v1_5.new(REQUEST_PRV_KEY)
        assert verifier.verify(SHA1.new(body),
                               self.signature), "Invalid signature"

        (magic, self.dna, self.sys_fw_ver, self.ver_code,
         self.pcba_rev) = unpack("<4s 16s 3I", body)
        self.serial = hexlify(self.dna)
Example #8
0
 def test1(self):
     padded = pad(b(""), 4)
     self.failUnless(padded == uh(b("04040404")))
     padded = pad(b(""), 4, 'pkcs7')
     self.failUnless(padded == uh(b("04040404")))
     back = unpad(padded, 4)
     self.failUnless(back == b(""))
Example #9
0
 def btn_action(self, event):
     # Проверить выбран ли алгоритм
     alg = self.cur_alg.get()
     if not alg:
         messagebox.showerror("Ошибка", "Выберите алгоритм из списка")
         return
     alg = self.algs[alg]
     # Получить ввод, ключ и вектор
     text = self.txt_input.get("0.0", END)[:-1].encode(
         "latin-1")  # прочитать ввод в поле ввода
     key = self.btn_key.get()
     vect = self.btn_vect.get()
     if key is False:
         messagebox.showerror("Ошибка", "Для работы необходим ключ")
         return
     if event == 2 and vect is False:
         messagebox.showerror(
             "Ошибка", "Для работы необходим вектор инициализации")
         return
     # Сделать работу
     if event == 1:
         cipher = alg["obj"].new(key, alg["obj"].MODE_CFB)
         res = cipher.encrypt(pad(text, alg["obj"].block_size))
         with open("vect", "wb") as f:
             f.write(cipher.iv)
         self.btn_vect.action("vect")
         self.res = res.decode("latin-1")
     else:
         cipher = alg["obj"].new(key, alg["obj"].MODE_CFB, iv=vect)
         res = unpad(cipher.decrypt(text), alg["obj"].block_size)
         self.res = res
     with open("sym", "wb") as f:
         f.write(res)
     self.set_output(self.res)
Example #10
0
def decryptFile(path, d):
    #input = open(path,'rb').read()
    n_fromCipher, e_fromCipher, key_S_fromCipher, iv_fromCipher = asnGenerator.decode(
        path)
    #print('n = ', n_fromCipher)
    #print('e = ', e_fromCipher)
    #print('key_s = ', key_S_fromCipher)

    print('d = ', d)
    print('Enc Key s = ', key_S_fromCipher)
    decryptedKey_S = RSA_data_Decryption(key_S_fromCipher, d, n_fromCipher)

    decryptedKey_S = decryptedKey_S.to_bytes(keyLen, 'big')
    print('Dec Key s = ', decryptedKey_S)

    with open('~tmp', 'rb') as file:
        data = file.read()
        #print('Cipher:\n')
        #print(data)
        print('Decrypted:\n')
        decryptedText = AES_data_Decryption(data, decryptedKey_S,
                                            iv_fromCipher)
        #pad(data,AES.block_size), decryptedKey_S, iv_fromCipher)
        decryptedText = unpad(decryptedText, AES.block_size)

    print(decryptedText)
    os.remove('~tmp')

    output = open(path + '.decrypted', 'wb')
    output.write(decryptedText)
    output.close()
Example #11
0
    def uncrypt_to_out(self):
        """ Même chose que pour le chiffrement"""
        # overture des fichiers
        file_in = open(self.get_in_file(), 'rb')
        file_out = open(self.get_out_file(), 'wb')

        data = b''
        for i in range(3):
            data += file_in.readline()
        file_out.write(data)  # ecriture de l'entête

        # dechiffrement
        encrypter = self.get_encrypter()
        file = bytes(file_in.read())
        block_size = self.get_block_size_uncrypt()
        blocks = [
            file[i * block_size:(i + 1) * block_size]
            for i in range(len(file) // block_size)
        ]
        for i in range(len(file) // block_size):
            blocks[i] = encrypter.uncrypt(blocks[i])
        # fermeture des fichiers
        out = concat_bytes(blocks)
        out = unpad(out, self.get_block_size_crypt(), style='iso7816')
        file_out.write(out)
        file_in.close()
        file_out.close()
Example #12
0
 def decrypt_data(self, data: str):
     data = data.encode()
     aes = AES.new(self.key, self.mode)
     pad_data = pad(data, AES.block_size, style=self.style)
     return str(
         unpad(aes.decrypt(base64.decodebytes(pad_data)),
               block_size=AES.block_size).decode('utf8'))
Example #13
0
def decrypt_data(encrypted_file, access_key):
    private_dir = os.path.join(os.pardir, "keys", "private", "private.pem")
    private_key = RSA.import_key(open(private_dir).read(),
                                 passphrase=hash_access_key(access_key))

    with open(encrypted_file, "rb") as file_in:
        enc_session_key, mode, iv, ciphertext = \
            [file_in.read(x) for x in (private_key.size_in_bytes(), 1, 16, -1)]

    # Decrypt the session key with the private RSA key
    cipher_rsa = PKCS1_OAEP.new(private_key)
    session_key = cipher_rsa.decrypt(enc_session_key)
    mode = int(mode.decode())
    # Decrypt the data with the AES session key
    if mode == AES.MODE_ECB:
        cipher_aes = AES.new(session_key, mode)
    else:
        cipher_aes = AES.new(session_key, mode, iv)
    data = unpad(cipher_aes.decrypt(ciphertext), AES.block_size)

    if os.path.basename(encrypted_file) == MESSAGE:
        messagebox.showinfo(title="Received a message",
                            message=f"New message:\n{data.decode()}")

    with open(encrypted_file, "wb") as decrypted_file:
        decrypted_file.write(data)
Example #14
0
 def remove_padding(data):
     try:
         transformed_data = unpad(data, block_size=BLOCK_SIZE)
     except ValueError:
         # when padding cannot be removed, sender entered incorrect access key and the data is random
         transformed_data = data  # return the random data
     return transformed_data
Example #15
0
def shared_key_decrypt(ciphertext, key):
    alg = key['alg']
    mode = key['mode']
    k = key['key']
    decrypt_kwargs = {'mode': BLOCK_MODES[alg][mode]}
    preamble_length = BLOCK_SIZES[alg]
    if mode in IV_MODES:
        #print("SYM_DECRYPT: Generating an IV", flush = True)
        decrypt_kwargs['iv'] = ciphertext[0:BLOCK_SIZES[alg]]
    elif mode == 'ctr':
        #print('SYM_DECRYPT: Generating a Counter', flush = True)
        preamble_length = preamble_length // 2
        n = ciphertext[0:(BLOCK_SIZES[alg] // 2)]
        decrypt_kwargs['nonce'] = n
    if alg == 'aes':
        #print('SYM_DECRYPT: USING AES')
        decrypter = AES.new(k, **decrypt_kwargs)
    elif alg == 'des3':
        #print('SYM_DECRYPT: USING DES3')
        decrypter = DES3.new(k, **decrypt_kwargs)
    elif alg == 'blowfish':
        #print('SYM_DECRYPT: USING Blowfish')
        decrypter = Blowfish.new(k, **decrypt_kwargs)
    serial_pt = decrypter.decrypt(ciphertext[preamble_length:])
    if mode in PAD_MODES:
        serial_pt = unpad(serial_pt, BLOCK_SIZES[alg])
    if serial_pt[0]:
        return pickle.loads(serial_pt[1:])
    else:
        return serial_pt[1:]
    return pt
Example #16
0
    def decode(self, data):
        if data == '':
            return data

        key_handle = DES3.new(self.uniq_id(), DES3.MODE_CBC, iv=b'\0\0\0\0\0\0\0\0')
        decrypted = unpad(key_handle.decrypt(b64decode(data)), DES3.block_size)
        return decrypted.decode('utf-8')
Example #17
0
def ecb_decrypt(encryptions, key):
    plaintext = ''

    for encrypted in encryptions:
        plaintext += aes_basic_decrypt(encrypted, key).decode('utf-8')

    return unpad(plaintext.encode('utf-8'), AES.block_size).decode('utf-8')
Example #18
0
def descifrar_aes(mensaje, fichero):
	# Obtengo mi clave privada 
	clave_privada = RSA.import_key(open(fichero, 'rb').read())
	
	# Saco el sobre (sabemos que ocupa 256 bytes)
	sobre = mensaje[:256]

	# Obtengo la clave simetrica descifrando el sobre
	cipher_rsa = PKCS1_OAEP.new(clave_privada)
	try:
		session_key = cipher_rsa.decrypt(sobre)
	except (ValueError):
		print('Error descifrando el sobre digital: La longitud del texto cifrado es incorrecta')
		return 	
	except (TypeError):
		print('Error descifrando el sobre digital: La clave RSA no tiene una mitad privada')
		return

	# Obtengo el vector de inicializacion (16 bytes) y descifro el mensaje
	iv = mensaje[256:256+16]
	cipher_aes = AES.new(session_key, AES.MODE_CBC, iv)
	try:
		texto16 = cipher_aes.decrypt(mensaje[256+16:])
	except (ValueError, TypeError):
		print('Error descifrando el mensaje')
		return 

	# Deshago el padding hecho en el mensaje descifrado 
	try:
		texto_claro = unpad(texto16, 16, style='pkcs7')
	except (ValueError):
		print('Error eliminando el padding del texto descifrado')
		return 

	return texto_claro
    def retrieve(self, input_image_file):
        """
        Retrieve the encrypted data from the image.
        :param input_image_file: Input image file path
        :return:
        """
        cypher_data = lsb.reveal(input_image_file)

        if not cypher_data:
            return None

        cypher_data = base64.b64decode(cypher_data)
        # Retrieve the dynamic initialization vector saved
        iv = cypher_data[:AES.block_size]
        # Retrieved the cypher data
        cypher_data = cypher_data[AES.block_size:]

        try:
            decryption_suite = AES.new(self.key, AES.MODE_CBC, iv)
            decrypted_data = unpad(decryption_suite.decrypt(cypher_data),
                                   self.block_size)
            try:
                return decrypted_data.decode('utf-8')
            except UnicodeDecodeError:
                # Binary data - returns as it is
                return decrypted_data
        except ValueError:
            return None
Example #20
0
    def button1Click(self, event):
        global send_msg, gmsg, useKey
        msg = self.text1.get("1.0", tk.END)
        self.text1.delete("1.0", tk.END)
        if msg != '\n':
            if useKey != "":
                cipher = AES.new(useKey, AES.MODE_CBC)
                ciphertext = cipher.encrypt(
                    pad(msg.encode('utf-8'), AES.block_size))
                msg = base64.b64encode(cipher.iv + ciphertext).decode()

                data = base64.b64decode(msg)
                iv = data[:16]
                cipher = AES.new(useKey, AES.MODE_CBC, iv=iv)
                original_data = unpad(cipher.decrypt(data[16:]),
                                      AES.block_size)
                self.text2.insert(tk.INSERT,
                                  'me(D): ' + original_data.decode() + '\n')
            elif msg.find("useKey") == 0:
                tmp = msg + "                                    "
                useKey = tmp[7:23].encode()
            self.text2.insert(tk.INSERT, 'me: ' + msg + '\n')
            gmsg = msg
            send_msg = True
        else:
            messagebox.showinfo("Error", "Write something!")
Example #21
0
def AESDecrypt(key, ciphertext, input="base64", output_type=None):
    """AES Decryption Function.

    :param key: basestring: Refer to the key parameter of :func:`AESEncrypt`

    :param ciphertext: basestring: Ciphertext message to be decrypted

    :param input: str: Input format: base64 (default) or hex (hexadecimal), refer to the output parameter of :func:`AESEncrypt`

    :param output_type: basestring: The type of decrypted string to be output, refer to the dst_type parameter of :func:`required_string` 

    :raises: AESError,binascii.Error,ValueError,TypeError

    :returns: Decrypted plaintext
    """
    if key and ciphertext:
        key = required_string(key, "bytes")
        if len(key) not in AES.key_size:
            raise AESError(
                "The key type error, resulting in length illegality")
        #: Encrypted in CBC mode, iv is fixed to the first 16 characters of the key
        aes = AES.new(key, AES.MODE_CBC, key[:16])
        ciphertext = a2b_hex(
            ciphertext) if input == "hex" else base64.b64decode(ciphertext)
        #: Remove fill
        plaintext = unpad(aes.decrypt(ciphertext), AES.block_size)
        return required_string(plaintext, output_type)
    else:
        raise AESError("The key or plaintext is not valid")
Example #22
0
def dec_real(ct: bytes, key) -> bytes:
    if ct is None: return None
    key = align16(key)
    cipher = AES.new(key, AES.MODE_CBC, iv=default_iv)
    pt: bytes = unpad(cipher.decrypt(ct), AES.block_size)
    # print("plain text: ", pt)
    return pt
Example #23
0
 def test1(self):
     padded = pad(b(""), 4)
     self.assertTrue(padded == uh(b("04040404")))
     padded = pad(b(""), 4, 'pkcs7')
     self.assertTrue(padded == uh(b("04040404")))
     back = unpad(padded, 4)
     self.assertTrue(back == b(""))
Example #24
0
def decrypt_message(key, message):
    key_ = b64decode(key)
    iv = b64decode(message[:24])
    word = b64decode(message[24:])
    crypter = AES.new(key_, AES.MODE_CBC, iv=iv)
    res = unpad(crypter.decrypt(word), AES.block_size)
    return res.decode('UTF-8')
Example #25
0
    def decrypt(self, data: bytes) -> bytes:
        """
        Have the serial-connected OpenTitan device decrypt the given data with
        the configured AES block cipher mode and the internally stored key.

        Parameters:
            data (bytes): data to decrypt

        Returns:
            bytes: decrypted data
        """
        if len(data) % AES.block_size:
            raise ValueError("len(data) must be multiple of AES block size")
        msg_len = len(data) // AES.block_size
        req = AesRequest(msg_len, self.cipher_mode, tc.aesModeDecrypt, self.iv)
        req.send(self.serial)
        ret = []
        for i in range(msg_len):
            self.serial.write(data[i * AES.block_size:(i + 1) *
                                   AES.block_size])
            if self.serial.read()[0] != tc.cryptoResponseAck:
                raise IOError(
                    f"OpenTitan device did not confirm decryption of block {i}"
                )
            ret += [self.serial.read(AES.block_size)]
        return unpad(b''.join(ret), AES.block_size)
Example #26
0
def get_result(result, secretKey, date):
    des3 = DES3.new(key=secretKey.encode(),
                    mode=DES3.MODE_CBC,
                    iv=date.encode())
    decrypted_data = des3.decrypt(base64.b64decode(result))
    plain_text = unpad(decrypted_data, DES3.block_size).decode()
    return plain_text
Example #27
0
def decrypt_user_credentials(encoded_key, encoded_iv, encoded_ct):
    encrypted_key = standard_b64decode(encoded_key)
    iv = standard_b64decode(encoded_iv)
    ciphertext = standard_b64decode(encoded_ct)
    result = get_private_key()
    if result.failure:
        return result
    private_key = RSA.import_key(result.value)
    cipher_rsa = PKCS1_OAEP.new(private_key, hashAlgo=SHA256)
    try:
        session_key = cipher_rsa.decrypt(encrypted_key)
        cipher_aes = AES.new(session_key, AES.MODE_CBC, iv)
        creds_plaintext = unpad(cipher_aes.decrypt(ciphertext), AES.block_size)
    except KeyError as e:
        error = f"Decryption Error: {repr(e)}"
        return Result.Fail(error)
    except ValueError as e:
        error = f"Decryption Error: {repr(e)}"
        return Result.Fail(error)

    split = creds_plaintext.decode("ascii").split(":")
    if len(split) != 2:
        error = 'User credentials not formatted correctly, expected 2 strings separated by ":" char.'
        return Result.Fail(error)
    user_creds = dict(email=split[0], password=split[1])
    return Result.Ok(user_creds)
 def test1(self):
     padded = pad(b(""), 4)
     self.failUnless(padded == uh(b("04040404")))
     padded = pad(b(""), 4, 'pkcs7')
     self.failUnless(padded == uh(b("04040404")))
     back = unpad(padded, 4)
     self.failUnless(back == b(""))
Example #29
0
def decrypt_data(aes_key, chipertext=None, iv=None, read_from_file=None):
    if read_from_file:
        with open(read_from_file, 'rb') as f:
            iv = f.read(16)
            chipertext = f.read()
    chiper = AES.new(aes_key, AES.MODE_CBC, iv)
    return unpad(chiper.decrypt(chipertext), AES.block_size)
Example #30
0
def decrypt(data, sKeyFileName=""):
    '''
    Symmetrically decrypt data 

    :param str data: The data to symmetrically decrypt
    :param str sKeyFileName: file that contains the encryption key, if empty: use default base of 'sCryptoKeyFileName'
    :return: decrypted data 
    :rtype: str
    :raises ValueError: N/A
    :raises TypeError: N/A    
    '''      


    if "ENC[" in data:
         start = data.find('ENC[') + 4
         end   = data.find(']', start)
         sPwd  = data[start:end]
    else:
        sPwd = data

    if len(sKeyFileName) < 1:
        sCryptoKeyFile = getCryptoKeyFile()
    else:
        sCryptoKeyFile = sKeyFileName

    key = getCryptoKey(sCryptoKeyFile)
    cipher = AES.new(key, AES.MODE_CBC, b64decode(sPwd[0:int(sPwd[-2:]):1]))
    value = unpad(cipher.decrypt(b64decode(sPwd[int(sPwd[-2:]) :len(sPwd):1])), AES.block_size).decode('utf-8')

    return value
Example #31
0
    def uncrypt(self, block):
        """ La fonction de déchiffrement"""

        byte_size = self.bit_size//8

        if len(block) == 4*byte_size:
            b_B1 = block[0:byte_size]
            b_B2 = block[byte_size:2*byte_size]
            b_c = block[2*byte_size:3*byte_size]
            b_v = block[3*byte_size:4*byte_size]
            
            B1 = int.from_bytes(b_B1, sys.byteorder)
            B2 = int.from_bytes(b_B2, sys.byteorder)
            c = int.from_bytes(b_c, sys.byteorder)
            v = int.from_bytes(b_v, sys.byteorder)

            # vérification de v
            p = self.p
            x1, x2, y1, y2 = self.x1, self.x2, self.y1, self.y2
            H = self.hashFunction((B1 + B2 + c) % p)
            v_bis = (pow(B1, x1, p) * pow(B2, x2, p) * pow(pow(B1, y1, p) * pow(B2, y2, p), H, p)) % p
            if v_bis != v:
                raise ValueError('Le message a été altéré après le chiffrement')
            # déchiffrement
            m = (inverse(pow(B1, self.w, p), p) * c) % p
            m = m.to_bytes(byte_size, sys.byteorder)
            return unpad(m, byte_size, 'iso7816')
        else:
            raise ValueError("Le block ne possède pas la bonne taille pour le déchiffrement")
Example #32
0
    def decrypt(data, passphrase):
        """Decrypt a piece of data using a passphrase and *PBES1*.

        The algorithm to use is automatically detected.

        :Parameters:
          data : byte string
            The piece of data to decrypt.
          passphrase : byte string
            The passphrase to use for decrypting the data.
        :Returns:
          The decrypted data, as a binary string.
        """

        enc_private_key_info = DerSequence().decode(data)
        encrypted_algorithm = DerSequence().decode(enc_private_key_info[0])
        encrypted_data = DerOctetString().decode(enc_private_key_info[1]).payload

        pbe_oid = DerObjectId().decode(encrypted_algorithm[0]).value
        cipher_params = {}
        if pbe_oid == "1.2.840.113549.1.5.3":
            # PBE_MD5_DES_CBC
            hashmod = MD5
            ciphermod = DES
        elif pbe_oid == "1.2.840.113549.1.5.6":
            # PBE_MD5_RC2_CBC
            hashmod = MD5
            ciphermod = ARC2
            cipher_params['effective_keylen'] = 64
        elif pbe_oid == "1.2.840.113549.1.5.10":
            # PBE_SHA1_DES_CBC
            hashmod = SHA1
            ciphermod = DES
        elif pbe_oid == "1.2.840.113549.1.5.11":
            # PBE_SHA1_RC2_CBC
            hashmod = SHA1
            ciphermod = ARC2
            cipher_params['effective_keylen'] = 64
        else:
            raise PbesError("Unknown OID for PBES1")

        pbe_params = DerSequence().decode(encrypted_algorithm[1], nr_elements=2)
        salt = DerOctetString().decode(pbe_params[0]).payload
        iterations = pbe_params[1]

        key_iv = PBKDF1(passphrase, salt, 16, iterations, hashmod)
        key, iv = key_iv[:8], key_iv[8:]

        cipher = ciphermod.new(key, ciphermod.MODE_CBC, iv, **cipher_params)
        pt = cipher.decrypt(encrypted_data)
        return unpad(pt, cipher.block_size)
Example #33
0
    def decrypt(self, key, entropy = None):
        keyHash = SHA1.new(key).digest()
        sessionKey = HMAC.new(keyHash, self['Salt'], ALGORITHMS_DATA[self['HashAlgo']][1])
        if entropy is not None:
            sessionKey.update(entropy)

        sessionKey = sessionKey.digest()

        # Derive the key
        derivedKey = self.deriveKey(sessionKey)

        cipher = ALGORITHMS_DATA[self['CryptAlgo']][1].new(derivedKey[:ALGORITHMS_DATA[self['CryptAlgo']][0]],
                                mode=ALGORITHMS_DATA[self['CryptAlgo']][2], iv=b'\x00'*ALGORITHMS_DATA[self['CryptAlgo']][3])
        cleartext = unpad(cipher.decrypt(self['Data']), ALGORITHMS_DATA[self['CryptAlgo']][1].block_size)

        # Now check the signature

        # ToDo Fix this, it's just ugly, more testing so we can remove one
        toSign = (self.rawData[20:][:len(self.rawData)-20-len(self['Sign'])-4])

        # Calculate the different HMACKeys
        keyHash2 = keyHash + b"\x00"*ALGORITHMS_DATA[self['HashAlgo']][1].block_size
        ipad = bytearray([i ^ 0x36 for i in bytearray(keyHash2)][:ALGORITHMS_DATA[self['HashAlgo']][1].block_size])
        opad = bytearray([i ^ 0x5c for i in bytearray(keyHash2)][:ALGORITHMS_DATA[self['HashAlgo']][1].block_size])
        a = ALGORITHMS_DATA[self['HashAlgo']][1].new(ipad)
        a.update(self['HMac'])

        hmacCalculated1 = ALGORITHMS_DATA[self['HashAlgo']][1].new(opad)
        hmacCalculated1.update(a.digest())

        if entropy is not None:
            hmacCalculated1.update(entropy)

        hmacCalculated1.update(toSign)

        hmacCalculated3 = HMAC.new(keyHash, self['HMac'], ALGORITHMS_DATA[self['HashAlgo']][1])
        if entropy is not None:
            hmacCalculated3.update(entropy)

        hmacCalculated3.update(toSign)

        if hmacCalculated1.digest() == self['Sign'] or hmacCalculated3.digest() == self['Sign']:
            return cleartext
        else:
            return None
 def test4(self):
     padded = pad(uh(b("1234567890")), 4, 'x923')
     self.failUnless(padded == uh(b("1234567890000003")))
     back = unpad(padded, 4, 'x923')
     self.failUnless(back == uh(b("1234567890")))
 def test3(self):
     padded = pad(uh(b("123456")), 4, 'x923')
     self.failUnless(padded == uh(b("12345601")))
     back = unpad(padded, 4, 'x923')
     self.failUnless(back == uh(b("123456")))
 def test2(self):
     padded = pad(uh(b("12345678")), 4, 'x923')
     self.failUnless(padded == uh(b("1234567800000004")))
     back = unpad(padded, 4, 'x923')
     self.failUnless(back == uh(b("12345678")))
 def test1(self):
     padded = pad(b(""), 4, 'x923')
     self.failUnless(padded == uh(b("00000004")))
     back = unpad(padded, 4, 'x923')
     self.failUnless(back == b(""))
 def test4(self):
     padded = pad(uh(b("1234567890")), 4, 'iso7816')
     self.failUnless(padded == uh(b("1234567890800000")))
     back = unpad(padded, 4, 'iso7816')
     self.failUnless(back == uh(b("1234567890")))
 def test3(self):
     padded = pad(uh(b("123456")), 4, 'iso7816')
     self.failUnless(padded == uh(b("12345680")))
     #import pdb; pdb.set_trace()
     back = unpad(padded, 4, 'iso7816')
     self.failUnless(back == uh(b("123456")))
Example #40
0
def decode(pem_data, passphrase=None):
    """Decode a PEM block into binary.

    Args:
      pem_data (string):
        The PEM block.
      passphrase (byte string):
        If given and the PEM block is encrypted,
        the key will be derived from the passphrase.

    Returns:
      A tuple with the binary data, the marker string, and a boolean to
      indicate if decryption was performed.

    Raises:
      ValueError: if decoding fails, if the PEM file is encrypted and no passphrase has
                  been provided or if the passphrase is incorrect.
    """

    # Verify Pre-Encapsulation Boundary
    r = re.compile(r"\s*-----BEGIN (.*)-----\s+")
    m = r.match(pem_data)
    if not m:
        raise ValueError("Not a valid PEM pre boundary")
    marker = m.group(1)

    # Verify Post-Encapsulation Boundary
    r = re.compile(r"-----END (.*)-----\s*$")
    m = r.search(pem_data)
    if not m or m.group(1) != marker:
        raise ValueError("Not a valid PEM post boundary")

    # Removes spaces and slit on lines
    lines = pem_data.replace(" ", '').split()

    # Decrypts, if necessary
    if lines[1].startswith('Proc-Type:4,ENCRYPTED'):
        if not passphrase:
            raise ValueError("PEM is encrypted, but no passphrase available")
        DEK = lines[2].split(':')
        if len(DEK) != 2 or DEK[0] != 'DEK-Info':
            raise ValueError("PEM encryption format not supported.")
        algo, salt = DEK[1].split(',')
        salt = unhexlify(tobytes(salt))
        if algo == "DES-CBC":
            # This is EVP_BytesToKey in OpenSSL
            key = PBKDF1(passphrase, salt, 8, 1, MD5)
            objdec = DES.new(key, DES.MODE_CBC, salt)
        elif algo == "DES-EDE3-CBC":
            # Note that EVP_BytesToKey is note exactly the same as PBKDF1
            key = PBKDF1(passphrase, salt, 16, 1, MD5)
            key += PBKDF1(key + passphrase, salt, 8, 1, MD5)
            objdec = DES3.new(key, DES3.MODE_CBC, salt)
        elif algo == "AES-128-CBC":
            key = PBKDF1(passphrase, salt[:8], 16, 1, MD5)
            objdec = AES.new(key, AES.MODE_CBC, salt)
        else:
            raise ValueError("Unsupport PEM encryption algorithm (%s)." % algo)
        lines = lines[2:]
    else:
        objdec = None

    # Decode body
    data = a2b_base64(''.join(lines[1:-1]))
    enc_flag = False
    if objdec:
        data = unpad(objdec.decrypt(data), objdec.block_size)
        enc_flag = True

    return (data, marker, enc_flag)
 def test1(self):
     padded = pad(b(""), 4, 'iso7816')
     self.failUnless(padded == uh(b("80000000")))
     back = unpad(padded, 4, 'iso7816')
     self.failUnless(back == b(""))
Example #42
0
    def decrypt(data, passphrase):
        """Decrypt a piece of data using a passphrase and *PBES2*.

        The algorithm to use is automatically detected.

        :Parameters:
          data : byte string
            The piece of data to decrypt.
          passphrase : byte string
            The passphrase to use for decrypting the data.
        :Returns:
          The decrypted data, as a binary string.
        """

        enc_private_key_info = DerSequence().decode(data, nr_elements=2)
        enc_algo = DerSequence().decode(enc_private_key_info[0])
        encrypted_data = DerOctetString().decode(enc_private_key_info[1]).payload

        pbe_oid = DerObjectId().decode(enc_algo[0]).value
        if pbe_oid != "1.2.840.113549.1.5.13":
            raise PbesError("Not a PBES2 object")

        pbes2_params = DerSequence().decode(enc_algo[1], nr_elements=2)

        ### Key Derivation Function selection
        kdf_info = DerSequence().decode(pbes2_params[0], nr_elements=2)
        kdf_oid = DerObjectId().decode(kdf_info[0]).value

        # We only support PBKDF2 or scrypt
        if kdf_oid == "1.2.840.113549.1.5.12":

            pbkdf2_params = DerSequence().decode(kdf_info[1], nr_elements=(2, 3, 4))
            salt = DerOctetString().decode(pbkdf2_params[0]).payload
            iteration_count = pbkdf2_params[1]
            if len(pbkdf2_params) > 2:
                kdf_key_length = pbkdf2_params[2]
            else:
                kdf_key_length = None
            if len(pbkdf2_params) > 3:
                raise PbesError("Unsupported PRF for PBKDF2")

        elif kdf_oid == "1.3.6.1.4.1.11591.4.11":

            scrypt_params = DerSequence().decode(kdf_info[1], nr_elements=(4, 5))
            salt = DerOctetString().decode(scrypt_params[0]).payload
            iteration_count, scrypt_r, scrypt_p = [scrypt_params[x]
                                                   for x in (1, 2, 3)]
            if len(scrypt_params) > 4:
                kdf_key_length = scrypt_params[4]
            else:
                kdf_key_length = None
        else:
            raise PbesError("Unsupported PBES2 KDF")

        ### Cipher selection
        enc_info = DerSequence().decode(pbes2_params[1])
        enc_oid = DerObjectId().decode(enc_info[0]).value

        if enc_oid == "1.2.840.113549.3.7":
            # DES_EDE3_CBC
            ciphermod = DES3
            key_size = 24
        elif enc_oid == "2.16.840.1.101.3.4.1.2":
            # AES128_CBC
            ciphermod = AES
            key_size = 16
        elif enc_oid == "2.16.840.1.101.3.4.1.22":
            # AES192_CBC
            ciphermod = AES
            key_size = 24
        elif enc_oid == "2.16.840.1.101.3.4.1.42":
            # AES256_CBC
            ciphermod = AES
            key_size = 32
        else:
            raise PbesError("Unsupported PBES2 cipher")

        if kdf_key_length and kdf_key_length != key_size:
            raise PbesError("Mismatch between PBES2 KDF parameters"
                            " and selected cipher")

        IV = DerOctetString().decode(enc_info[1]).payload

        # Create cipher
        if kdf_oid == "1.2.840.113549.1.5.12": # PBKDF2
            key = PBKDF2(passphrase, salt, key_size, iteration_count)
        else:
            key = scrypt(passphrase, salt, key_size, iteration_count,
                         scrypt_r, scrypt_p)
        cipher = ciphermod.new(key, ciphermod.MODE_CBC, IV)

        # Decrypt data
        pt = cipher.decrypt(encrypted_data)
        return unpad(pt, cipher.block_size)