PyCrypto Cyphertext неверная длина даже с данными одного символа - PullRequest
0 голосов
/ 18 февраля 2019

Я хочу зашифровать / расшифровать набор данных, который содержится в файле .csv.Я генерирую свои открытые / закрытые ключи RSA с помощью этого кода:

import Crypto
from Crypto.PublicKey import RSA

key = RSA.generate(2048)

k = key.exportKey('PEM')
p = key.publickey().exportKey('PEM')

with open('private.pem', 'w') as kf:
    kf.write(k.decode())
    kf.close()

with open('public.pem', 'w') as pf:
    pf.write(p.decode())
    pf.close()

with open('private.pem','r') as fk:
    priv = fk.read()
    fk.close()

with open('public.pem','r') as fp:
    pub = fp.read()
    fp.close()

privat = RSA.importKey(priv)
public = RSA.importKey(pub)

if key == privat:
    print('Private key has been successfuly write')
if key.publickey() == public:
    print('Public key has been successfuly write')

Затем я без проблем шифрую этот код:

import Crypto
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP

with open('public.pem','r') as fp:
    pub = fp.read()
    fp.close()

public = RSA.importKey(pub)

#stockage du fichier dans une variable rep
fichier = open('test.csv', 'r')
rep = fichier.read()
fichier.close()

#eliminations des spaces
rep = rep.replace(' ', '')

#encodage pour type bytes
rep = rep.encode()

#decoupage en mot de 10 chars
rep = [rep[i:i+10] for i in range(0, len(rep), 10)]

cipher = PKCS1_OAEP.new(public)

fichier2 = open('encrypted.csv', 'a')
for i in rep:
    encrypted_line = cipher.encrypt(i)
    fichier2.write(str(encrypted_line))
    fichier2.write('\n')

fichier2.close()

Я могу изменить разделение своих данных, изменивэта строка:

rep = [rep [i: i + n] для i в диапазоне (0, len (rep), n)]

Эта строка отделяетсямои данные по группам из n символов

Вот мой код для расшифровки данных, он вызывает:

ValueError: зашифрованный текст с неверной длиной.

import Crypto
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP

with open('private.pem','r') as fk:
    priv = fk.read()
    fk.close()

private = RSA.importKey(priv)

fichier = open('encrypted.csv', 'r')
rep = fichier.read().splitlines()
fichier.close()

cipher = PKCS1_OAEP.new(private)

fichier2 = open('decrypted.csv', 'a')
for i in rep:
    decrypted_line = cipher.decrypt(i)
    decrypted_line = decrypted_line.decode('utf-8')
    fichier2.write(str(encrypted_line))

fichier2.close()

Я попытался закодировать пример файла, и это вызвало ошибку ValueError.Затем я пытаюсь работать с файлом, который содержит только один символ, непосредственно в интерпретаторе Python.Шифрование работало хорошо, но дешифрование прерывалось с той же ошибкой, что и выше.

1 Ответ

0 голосов
/ 18 февраля 2019

Основная проблема с кодом - использование символов новой строки для разделения фрагментов зашифрованных данных.Зашифрованные данные могут уже содержать символы новой строки, поэтому попытка разбить зашифрованные данные на строки может привести к частичным фрагментам, что приведет к увеличению значения ValueError, которое вы видите при расшифровке.

Вторая проблема заключается в том, что зашифрованные файлыоткрываются в текстовом режиме.При работе с зашифрованными данными открывайте файлы в двоичном режиме.Зашифрованные bytes вряд ли могут быть декодированы до str, поэтому использование текстового режима приведет к ошибкам кодирования или декодирования.

Эта версия вашего кода работает:

import functools

from Crypto.PublicKey import RSA 
from Crypto.Cipher import PKCS1_OAEP

if __name__ == '__main__':

    # Encrypt

    with open('public.pem', 'r') as fp: 
        pub = fp.read()
        fp.close()

    public = RSA.importKey(pub)

    # tockage du fichier dans une variable rep
    with open('test.csv', 'r') as fichier:
        rep = fichier.read()

    # liminations des spaces
    rep = rep.replace(' ', '') 

    # ncodage pour type bytes
    rep = rep.encode()

    cipher = PKCS1_OAEP.new(public)

    # decoupage en mot de 10 chars
    rep = [rep[i:i+10] for i in range(0, len(rep), 10)]

    # Open the file in binary mode so we can write bytes.
    with open('encrypted.csv', 'wb') as fichier2:
        for i in rep:
            fichier2.write(cipher.encrypt(i))

    # Decrypt
    with open('private.pem', 'r') as fk: 
        priv = fk.read()

    private = RSA.importKey(priv)

    CHUNK_SIZE = 256 
    # Open the file in binary mode so we can read bytes.
    with open('encrypted.csv', 'rb') as fichier:
        # Create an iterator that will return chunks of the correct size.
        chunker = iter(functools.partial(fichier.read, CHUNK_SIZE), b'')
        rep = list(chunker)

    cipher = PKCS1_OAEP.new(private)

    with open('decrypted.csv', 'w') as fichier2:
        for i in rep:
            decrypted_line = cipher.decrypt(i)
            fichier2.write(decrypted_line.decode())

Вместоразбивая зашифрованные данные на новые строки, этот код считывает из файла куски по 256 байт, поскольку процесс шифрования генерирует 256 байтов для каждого блока ввода.Я не криптолог, поэтому возможно, что это не всегда так.В этом случае может быть лучше зашифровать (или расшифровать) все данные за один шаг.

...