def send(dance_result, s, voltage, current, power, energy):
    private_msg = """#{} | {}V | {}A | {}W | {}Wh""".format(
        dance_result, voltage, current, power, energy)  # 34 bytes
    private_msg = bytes(private_msg, 'utf-8')
    padding_character = "{"
    secret_key = b"sixteen byte key"
    iv = Random.new().read(AES.block_size)
    cipher = AES.new(secret_key, AES.MODE_CBC, iv)
    padded = pad(private_msg, AES.block_size)
    # print(private_msg)
    # print(len(private_msg))
    # print(padded)
    # print(len(padded))
    ct_bytes = cipher.encrypt(pad(private_msg, AES.block_size))
    ct = base64.b64encode(iv + ct_bytes)
    # print(secret_key)
    # print(iv)
    # print(len(iv))
    # print("cipher ")
    # print(cipher)
    # print(ct_bytes)
    # print(len(ct_bytes))
    # print(ct)
    # print(len(ct))
    msg = s.send(ct)
Пример #2
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(""))
 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(""))
Пример #4
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(""))
Пример #5
0
 def encrypt(login, password):
     login = bytes(login, encoding = 'utf-8')
     password = bytes(password, encoding = 'utf-8')
     salt = get_random_bytes(AES.block_size)
     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)
     crypto_login = cipher.encrypt(pad(login, 32))
     crypto_password = cipher.encrypt(pad(password, 32))
     return crypto_login, crypto_password, salt
Пример #6
0
 def finish(self):
     if self.done:
         raise Exception("Already completed")
     self.done = True
     if self.prev:
         padded = pad(self.prev, self.cipher.block_size)
     else:
         padded = pad(b'', self.cipher.block_size)
     return self.cipher.encrypt(padded)
Пример #7
0
def flag2(s, cipher, mac, flag):
    bts = bytes_to_long(binascii.unhexlify(mac))
    m = bytes_to_long(pad(flag.encode(), 16))
    stream = m ^ bts
    newstr = flag[:-4] + 'getflag'
    nm = pad(newstr.encode(), 16)
    mac = binascii.hexlify(long_to_bytes(bytes_to_long(nm) ^ stream))
    s.sendlineafter('>', '1'.encode())
    s.sendlineafter(':', binascii.hexlify(newstr.encode()))
    message = s.recvline().decode().strip()
    s.sendlineafter('>', '3'.encode())
    s.sendlineafter(':', (message + '||' + mac.decode()).encode())
    flag2 = s.recvline().decode().strip()
    return flag2
Пример #8
0
def encrypt(key, data, _iv=None):
    _key = pad(bytes(key.encode('utf-8')), AES.block_size)
    _data = pad(bytes(data.encode('utf-8')), AES.block_size)

    if _iv is None:
        cipher = AES.new(_key, AES.MODE_CBC)
    else:
        _iv = bytes(_iv.encode('utf-8'))
        cipher = AES.new(_key, AES.MODE_CBC, _iv)
    ct_bytes = cipher.encrypt(_data)
    iv = b64encode(cipher.iv).decode('utf-8')
    ct = b64encode(ct_bytes).decode('utf-8')
    result = json.dumps({'iv': iv, 'ciphertext': ct})
    return result
Пример #9
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')
Пример #10
0
def encrypt_save_data(data: str) -> str:
    global SAVE_KEY
    global SAVE_IV
    return str(
        base64.b64encode(
            AES.new(SAVE_KEY, AES.MODE_CBC, iv=SAVE_IV).encrypt(
                pad(bytes(data, "utf8"), AES.block_size))), "utf8")
Пример #11
0
    def _encrypt_files(files, farc_type):
        for fname, info in files.items():
            if not info['flags']['encrypted']:
                continue

            data = info['data']

            if farc_type['encryption_type'] == 'DT':
                while len(data) % 16:
                    data += b'\x00'
                cipher = AES.new(b'project_diva.bin', AES.MODE_ECB)
                data = cipher.encrypt(data)
            elif farc_type['encryption_type'] == 'FT':
                data = pad(data, 16, 'pkcs7')
                if getenv('PYFARC_NULL_IV'):
                    iv = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
                else:
                    iv = token_bytes(16)
                cipher = AES.new(
                    b'\x13\x72\xD5\x7B\x6E\x9E\x31\xEB\xA2\x39\xB8\x3C\x15\x57\xC6\xBB',
                    AES.MODE_CBC,
                    iv=iv)
                data = iv + cipher.encrypt(data)

                # encrypted FT FARC "compressed" length seems to include IV and be aligned
                info['len_compressed'] = len(data)

            info['data'] = data
Пример #12
0
def encrypt(key, fileIn, fileOut=None, chunksize=64 * 1024):
    key = SHA256Hash(key).digest()
    if not fileOut:
        fileOut = fileIn + '.crypt'

    iv = Random.new().read(AES.block_size)
    encryptor = AES.new(key, AES.MODE_CBC, iv)
    filesize = os.path.getsize(fileIn)
    print(filesize)
    encfilesize = filesize + (AES.block_size - filesize % AES.block_size) + 24
    print(encfilesize)
    pbar = tqdm(desc='Encrypting',
                total=encfilesize,
                unit='Bytes',
                unit_scale=1)

    with open(fileIn, 'rb') as infile:
        with open(fileOut, 'wb') as outfile:
            outfile.write(struct.pack('<Q', filesize))
            outfile.write(iv)
            pbar.update(24)

            while True:
                chunk = infile.read(chunksize)
                if len(chunk) == 0:
                    break
                elif len(chunk) % IV_BLOCK_SIZE != 0:
                    chunk = pad(chunk, IV_BLOCK_SIZE)

                outfile.write(encryptor.encrypt(chunk))
                pbar.update(chunksize)

    pbar.close()
    _tmp = input('Press enter to continue...')
Пример #13
0
    def encrypt(self, plaintext):
        cipher = AES.new(self.key, AES.MODE_CBC, self.iv)

        ciphertext = cipher.encrypt(
            pad(str(plaintext).encode('utf-8'), AES.block_size))

        return ciphertext.hex()
Пример #14
0
def encrypt(content: bytes, password: str) -> str:
    """
    Encrypt html content, act like `staticrypt`.

    Args:
        content: html content bytes
        password: password to encrypt and decrypt

    Returns:
        The encrypted contend
    """

    salt = urandom(16)
    iv = urandom(16)
    key = PBKDF2(password=password, salt=salt, dkLen=32, count=1000)
    cryptor = AES.new(key, AES.MODE_CBC, iv)

    pkcs7_content = pad(content, AES.block_size)

    aes_encrypted_bytes = b64encode(cryptor.encrypt(pkcs7_content))

    aes_encrypted_content = (salt.hex() + iv.hex() +
                             aes_encrypted_bytes.decode("utf-8"))

    hmac_signature = hmac.new(key=sha256(
        password.encode("utf-8")).hexdigest().encode("utf-8"),
                              msg=aes_encrypted_content.encode("utf-8"),
                              digestmod=sha256).hexdigest()

    return hmac_signature + aes_encrypted_content
Пример #15
0
def AESEncrypt(key, plaintext, output="base64", output_type=None):
    """AES Encryption Function.

    :param key: basestring: 16 24 32 bytes with ASCII.

    :param plaintext: basestring: Plaintext message to be encrypted

    :param output: str: Output format: base64 (default), hex (hexadecimal)

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

    :raises: AESError,ValueError

    :returns: Encrypted ciphertext
    """
    if key and plaintext:
        key = required_string(key, "bytes")
        if len(key) not in AES.key_size:
            raise AESError(
                "The key type error, resulting in length illegality")
        #: Pad fill requires bytes type
        padding = pad(required_string(plaintext, "bytes"), AES.block_size)
        #: 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 = aes.encrypt(padding)
        crypted_str = b2a_hex(
            ciphertext) if output == "hex" else base64.b64encode(ciphertext)
        return required_string(crypted_str, output_type)
    else:
        raise AESError("The key or plaintext is not valid")
Пример #16
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)
Пример #17
0
    def crypt_to_out(self):
        """ On suppose que notre class a bien été initialisé
        et possède les attributs file_in et file_out
        on copie les trois premières lignes du fichiers avant tout
        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

        # chiffrement normal
        encrypter = self.get_encrypter()
        file = bytes(file_in.read())
        block_size = self.get_block_size_crypt()
        padded_file = pad(file, block_size, style='iso7816')
        blocks = [
            padded_file[i * block_size:(i + 1) * block_size]
            for i in range(len(padded_file) // block_size)
        ]
        for block in blocks:
            crypted_block = encrypter.crypt(block)
            file_out.write(crypted_block)
        # fermeture des fichiers
        file_in.close()
        file_out.close()
Пример #18
0
def encrypt_file(input_file_name: str,
                 output_file_name: str = None,
                 key: str = None):

    if not key:
        key = get_random_bytes(32)

    with open('key.bin', 'wb') as key_file:
        key_file.write(key)

    if not output_file_name:
        output_file_name = input_file_name.split('.')[0] + '.enc'

    with open(input_file_name, 'rb') as fin:
        with open(output_file_name, 'wb') as fout:
            encryptor = AES.new(key, AES.MODE_CBC)
            fout.write(struct.pack('<Q', os.path.getsize(input_file_name)))
            fout.write(encryptor.iv)

            while True:
                chunk = fin.read(2**16)
                if not chunk:
                    break
                elif len(chunk) % AES.block_size != 0:
                    chunk = pad(chunk, AES.block_size)

                fout.write(encryptor.encrypt(chunk))
Пример #19
0
def AESEncrypt(text, key, BLOCK_SIZE=16):
    nonce = get_random_bytes(12)
    cipher = AES.new(key, AES.MODE_CTR,
                     nonce=nonce)  # new AES cipher using key generated
    cipher_text_bytes = cipher.encrypt(pad(text, BLOCK_SIZE))  # encrypt data
    cipher_text_bytes = cipher_text_bytes + nonce
    return cipher_text_bytes
Пример #20
0
def encrypt(data, sKeyFileName=""):
    '''
    Symmetrically encrypt data 

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

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

    key = getCryptoKey(sCryptoKeyFile)
    # cipher = AES.new(key.encode(), AES.MODE_CBC)
    cipher = AES.new(key, AES.MODE_CBC)
    value = b64encode(cipher.iv).decode('utf-8') + b64encode(cipher.encrypt(pad(sPwd.encode(), AES.block_size))).decode('utf-8') + str(len(b64encode(cipher.iv).decode('utf-8')))
    sPwd = "ENC[" + value + "]"
    
    return sPwd
Пример #21
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'))
Пример #22
0
    def crypt(self, block):
        """ La fonction de chiffrement, à implémenter"""
        m = int.from_bytes(block, sys.byteorder)
        if m > self.p or len(block) * 8 >= self.bit_size:
            raise OverflowError('block too long')
        padded_block = pad(block, self.bit_size // 8, 'iso7816')
        bit_size = self.bit_size
        p = self.p
        a1 = self.a1
        a2 = self.a2
        W = self.W
        X = self.X
        Y = self.Y
        b = randbelow(p)

        B1 = pow(a1, b, p)
        B2 = pow(a2, b, p)
        c = (pow(W, b, p) * int.from_bytes(padded_block, sys.byteorder)) % p

        H = self.hashFunction((B1 + B2 + c) % p)
        v = (pow(X, b, p) * pow(Y, b*H, p)) % p

        # return everything to bytes
        b_B1 = B1.to_bytes(bit_size//8, sys.byteorder)
        b_B2 = B2.to_bytes(bit_size//8, sys.byteorder)
        b_c = c.to_bytes(bit_size//8, sys.byteorder)
        b_v = v.to_bytes(bit_size//8, sys.byteorder)

        return b_B1 + b_B2 + b_c + b_v
Пример #23
0
def check_mode(mode, mode_str):
    print("############################  {}. {}  #################################".format(mode, mode_str))
    key = b"some key"
    message = "привет мир и так далее и тому подобное тут специально много текста чтобы блоков было больше"
    plaintext = pad(bytes(message, encoding='utf-8'), 8)

    iv = Random.new().read(DES.block_size)  # эта штука не используется, хотя можно. тут пусть останется для красоты

    print("Открытый текст")
    print(to_str_b(plaintext))

    msg = get_DES(key, mode).encrypt(plaintext)

    print("Закрытый текст")
    print(to_str_b(msg))

    msg_err = list(msg).copy()
    msg_err[24] = (msg_err[5] + 1) % 256  # делаем ошибку
    msg_err = bytes(msg_err)
    print("Закрытый текст с ошибкой")
    print(to_str_b(msg_err))
    show_diff(to_str_b(msg), to_str_b(msg_err))

    print("Расшифрованный текст")
    decr = get_DES(key, mode).decrypt(msg)
    print(to_str_b(decr))
    # print(decr.decode('utf-8')) # <- это вывод расшифрованного текста

    print("Расшифрованный текст с ошибкой")
    decr_err = get_DES(key, mode).decrypt(msg_err)
    print(to_str_b(decr_err))
    # print(decr_err.decode('utf-8')) # <- а тут лучше не выводить, это же код с ошибкой
    show_diff(to_str_b(decr), to_str_b(decr_err))
    print("##############################################################################")
Пример #24
0
 def encode(self, data):
     key_handle = DES3.new(self.uniq_id(),
                           DES3.MODE_CBC,
                           iv=b'\0\0\0\0\0\0\0\0')
     encrypted = key_handle.encrypt(
         pad(data.encode('utf-8'), DES3.block_size))
     return b64encode(encrypted)
Пример #25
0
    def encrypt(self, data: bytes) -> bytes:
        """
        Have the serial-connected OpenTitan device encrypt the given data with
        the configured AES block cipher mode and the internally stored key.

        Parameters:
            data (bytes): data to encrypt (automatically padded to multiple of
                AES block size)

        Returns:
            bytes: encrypted data
        """
        data = pad(data, AES.block_size)
        msg_len = len(data) // AES.block_size
        req = AesRequest(msg_len, self.cipher_mode, tc.aesModeEncrypt, 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 encryption of block {i}"
                )
            ret += [self.serial.read(AES.block_size)]
        return b''.join(ret)
def _encrypt(connection_info_str, public_key):
    """Encrypt the connection information using a generated AES key that is then encrypted using
       the public key passed from the server.  Both are then returned in an encoded JSON payload.

       This code also exists in the Python kernel-launcher's launch_ipykernel.py script.
    """
    aes_key = get_random_bytes(16)
    cipher = AES.new(aes_key, mode=AES.MODE_ECB)

    # Encrypt the connection info using the aes_key
    encrypted_connection_info = cipher.encrypt(pad(connection_info_str, 16))
    b64_connection_info = base64.b64encode(encrypted_connection_info)

    # Encrypt the aes_key using the server's public key
    imported_public_key = RSA.importKey(base64.b64decode(public_key.encode()))
    cipher = PKCS1_v1_5.new(key=imported_public_key)
    encrypted_key = base64.b64encode(cipher.encrypt(aes_key))

    # Compose the payload and Base64 encode it
    payload = {
        "version": LAUNCHER_VERSION,
        "key": encrypted_key.decode(),
        "conn_info": b64_connection_info.decode()
    }
    b64_payload = base64.b64encode(
        json.dumps(payload).encode(encoding='utf-8'))
    return b64_payload
Пример #27
0
def _encrypt_data(data, mode):
    recipient_key_path = os.path.join(os.pardir, "keys", "public",
                                      "receiver.pem")
    encrypted_file = tempfile.mktemp()

    recipient_key = RSA.import_key(open(recipient_key_path).read())
    session_key = get_random_bytes(16)

    # Encrypt the session key with the public RSA key
    cipher_rsa = PKCS1_OAEP.new(recipient_key)
    enc_session_key = cipher_rsa.encrypt(session_key)

    # Encrypt the data with the AES session key
    cipher_aes = AES.new(session_key, mode)
    ciphertext = cipher_aes.encrypt(pad(data, AES.block_size))

    iv = cipher_aes.iv if mode != AES.MODE_ECB else get_random_bytes(16)
    with open(encrypted_file, "wb") as file_out:
        [
            file_out.write(x)
            for x in (enc_session_key, str(mode).encode(), iv, ciphertext)
        ]
        file_out.close()

    return encrypted_file
Пример #28
0
    def generate(self, data: bytes) -> bytes:
        """Generate an encrypted packet from plain data.

        Args:
            data (bytes): 
        """

        cipher = AES.new(self.key, AES.MODE_CBC, iv=self.iv)
        encrypted = cipher.encrypt(pad(data, 64, style='pkcs7'))

        head = struct.pack(
            '!BBHIII16s',
            self.magic[0],
            self.magic[1],  # const magic value
            len(encrypted) + 32,
            self.unknown1,  # unknown const
            self.device_id,  # unknown const
            self.stamp,
            self.token  # overwritten by the MD5 checksum later
        )

        packet = bytearray(head + encrypted)
        checksum = self.md5sum(bytes(packet))
        for i in range(0, 16):
            packet[i + 16] = checksum[i]
        return bytes(packet)
    def hide(self, input_filename, output_filename, data):
        """
        Encrypt and save the data inside the image.
        :param input_filename: Input image file path
        :param output_filename: Output image file path
        :param data: Information to be encrypted and saved
        :return:
        """
        # Generate a random initialization vector
        iv = Random.new().read(AES.block_size)
        encryption_suite = AES.new(self.key, AES.MODE_CBC, iv)

        # If it is string convert to byte string before use it
        if isinstance(data, str):
            data = data.encode()

        # Encrypt the random initialization vector concatenated
        # with the padded data
        cypher_data = encryption_suite.encrypt(iv + pad(data, self.block_size))

        # Convert the cypher byte string to a base64 string to avoid
        # decode padding error
        cypher_data = base64.b64encode(cypher_data).decode()

        # Hide the encrypted message in the image with the LSB
        # (Least Significant Bit) technique.
        secret = lsb.hide(input_filename, cypher_data)
        # Save the image file
        secret.save(output_filename)
Пример #30
0
 def __init__(self, path):
     self._path = pathlib.Path(path).as_uri()
     self._padded = pad(
         struct.pack('>H', len(self._path)) +
         bytearray(self._path, 'utf-8'), len(KEY))
     self.hash = hashlib.md5(
         AES.new(KEY, AES.MODE_ECB).encrypt(self._padded)).hexdigest()
Пример #31
0
 def _encrypt_payload(self, payload):
     self._update_client_key()
     aes = self._handle_AES(self.client_key)
     paded_message = pad(bytes(payload.encode("utf8")), 16, style="pkcs7")
     encoded_message = aes.encrypt(paded_message).hex().upper()
     digest = self._create_digest(self.client_key, encoded_message)
     return self.client_key + encoded_message + digest
Пример #32
0
def encode(data, marker, passphrase=None, randfunc=None):
    """Encode a piece of binary data into PEM format.

    Args:
      data (byte string):
        The piece of binary data to encode.
      marker (string):
        The marker for the PEM block (e.g. "PUBLIC KEY").
        Note that there is no official master list for all allowed markers.
        Still, you can refer to the OpenSSL_ source code.
      passphrase (byte string):
        If given, the PEM block will be encrypted. The key is derived from
        the passphrase.
      randfunc (callable):
        Random number generation function; it accepts an integer N and returns
        a byte string of random data, N bytes long. If not given, a new one is
        instantiated.

    Returns:
      The PEM block, as a string.

    .. _OpenSSL: https://github.com/openssl/openssl/blob/master/include/openssl/pem.h
    """

    if randfunc is None:
        randfunc = get_random_bytes

    out = "-----BEGIN %s-----\n" % marker
    if passphrase:
        # We only support 3DES for encryption
        salt = randfunc(8)
        key = PBKDF1(passphrase, salt, 16, 1, MD5)
        key += PBKDF1(key + passphrase, salt, 8, 1, MD5)
        objenc = DES3.new(key, DES3.MODE_CBC, salt)
        out += "Proc-Type: 4,ENCRYPTED\nDEK-Info: DES-EDE3-CBC,%s\n\n" %\
            tostr(hexlify(salt).upper())
        # Encrypt with PKCS#7 padding
        data = objenc.encrypt(pad(data, objenc.block_size))
    elif passphrase is not None:
        raise ValueError("Empty password")

    # Each BASE64 line can take up to 64 characters (=48 bytes of data)
    # b2a_base64 adds a new line character!
    chunks = [tostr(b2a_base64(data[i:i + 48]))
              for i in range(0, len(data), 48)]
    out += "".join(chunks)
    out += "-----END %s-----" % marker
    return out
Пример #33
0
    def encrypt(data, passphrase, protection, prot_params=None, randfunc=None):
        """Encrypt a piece of data using a passphrase and *PBES2*.

        :Parameters:
          data : byte string
            The piece of data to encrypt.
          passphrase : byte string
            The passphrase to use for encrypting the data.
          protection : string
            The identifier of the encryption algorithm to use.
            The default value is '``PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC``'.
          prot_params : dictionary
            Parameters of the protection algorithm.

            +------------------+-----------------------------------------------+
            | Key              | Description                                   |
            +==================+===============================================+
            | iteration_count  | The KDF algorithm is repeated several times to|
            |                  | slow down brute force attacks on passwords    |
            |                  | (called *N* or CPU/memory cost in scrypt).    |
            |                  |                                               |
            |                  | The default value for PBKDF2 is 1 000.        |
            |                  | The default value for scrypt is 16 384.       |
            +------------------+-----------------------------------------------+
            | salt_size        | Salt is used to thwart dictionary and rainbow |
            |                  | attacks on passwords. The default value is 8  |
            |                  | bytes.                                        |
            +------------------+-----------------------------------------------+
            | block_size       | *(scrypt only)* Memory-cost (r). The default  |
            |                  | value is 8.                                   |
            +------------------+-----------------------------------------------+
            | parallelization  | *(scrypt only)* CPU-cost (p). The default     |
            |                  | value is 1.                                   |
            +------------------+-----------------------------------------------+


          randfunc : callable
            Random number generation function; it should accept
            a single integer N and return a string of random data,
            N bytes long. If not specified, a new RNG will be
            instantiated from ``Cryptodome.Random``.

        :Returns:
          The encrypted data, as a binary string.
        """

        if prot_params is None:
            prot_params = {}

        if randfunc is None:
            randfunc = Random.new().read

        if protection == 'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC':
            key_size = 24
            module = DES3
            cipher_mode = DES3.MODE_CBC
            enc_oid = "1.2.840.113549.3.7"
        elif protection in ('PBKDF2WithHMAC-SHA1AndAES128-CBC',
                'scryptAndAES128-CBC'):
            key_size = 16
            module = AES
            cipher_mode = AES.MODE_CBC
            enc_oid = "2.16.840.1.101.3.4.1.2"
        elif protection in ('PBKDF2WithHMAC-SHA1AndAES192-CBC',
                'scryptAndAES192-CBC'):
            key_size = 24
            module = AES
            cipher_mode = AES.MODE_CBC
            enc_oid = "2.16.840.1.101.3.4.1.22"
        elif protection in ('PBKDF2WithHMAC-SHA1AndAES256-CBC',
                'scryptAndAES256-CBC'):
            key_size = 32
            module = AES
            cipher_mode = AES.MODE_CBC
            enc_oid = "2.16.840.1.101.3.4.1.42"
        else:
            raise ValueError("Unknown PBES2 mode")

        # Get random data
        iv = randfunc(module.block_size)
        salt = randfunc(prot_params.get("salt_size", 8))

        # Derive key from password
        if protection.startswith('PBKDF2'):
            count = prot_params.get("iteration_count", 1000)
            key = PBKDF2(passphrase, salt, key_size, count)
            kdf_info = DerSequence([
                    DerObjectId("1.2.840.113549.1.5.12"),   # PBKDF2
                    DerSequence([
                        DerOctetString(salt),
                        DerInteger(count)
                    ])
            ])
        else:
            # It must be scrypt
            count = prot_params.get("iteration_count", 16384)
            scrypt_r = prot_params.get('block_size', 8)
            scrypt_p = prot_params.get('parallelization', 1)
            key = scrypt(passphrase, salt, key_size,
                         count, scrypt_r, scrypt_p)
            kdf_info = DerSequence([
                    DerObjectId("1.3.6.1.4.1.11591.4.11"),  # scrypt
                    DerSequence([
                        DerOctetString(salt),
                        DerInteger(count),
                        DerInteger(scrypt_r),
                        DerInteger(scrypt_p)
                    ])
            ])

        # Create cipher and use it
        cipher = module.new(key, cipher_mode, iv)
        encrypted_data = cipher.encrypt(pad(data, cipher.block_size))
        enc_info = DerSequence([
                DerObjectId(enc_oid),
                DerOctetString(iv)
        ])

        # Result
        enc_private_key_info = DerSequence([
            # encryptionAlgorithm
            DerSequence([
                DerObjectId("1.2.840.113549.1.5.13"),   # PBES2
                DerSequence([
                    kdf_info,
                    enc_info
                ]),
            ]),
            DerOctetString(encrypted_data)
        ])
        return enc_private_key_info.encode()
 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 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 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 test1(self):
     padded = pad(b(""), 4, 'iso7816')
     self.failUnless(padded == uh(b("80000000")))
     back = unpad(padded, 4, 'iso7816')
     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")))