Не удается извлечь исходное изображение из зашифрованного изображения в Python с использованием PIL

#python #image #encryption #python-imaging-library #mod

#python #изображение #шифрование #python-imaging-library #мод

Вопрос:

Я пишу скрипт, который может шифровать и расшифровывать изображение с использованием алгоритма RSA. Мой открытый ключ равен (7, 187), а закрытый ключ равен (23,187) теперь вычисление для шифрования правильное, как и для записи в матрице изображения, 41 зашифрованное значение равно 46. Но когда происходит расшифровка, это не дает соответствующего результата, например, для 46, это дает 136, и для каждой записи 46 в матрице шифрования результат, который я получаю, равен 136 в матрице дешифрования. И я не знаю, почему это происходит. Когда я выполняю то же вычисление в командной строке python (или оболочке), он выдает правильный ответ.

В сценарии я сначала преобразую RGB-изображение в оттенки серого, а затем преобразую его в 2d-массив numpy, затем для каждого элемента я применяю алгоритм RSA (ключи) и затем сохраняю его как изображение. Затем я применяю ключ дешифрования в зашифрованной матрице, и тогда возникает проблема. Вот код:

 from PIL import Image
import numpy as np
from pylab import * 
#encryption

img1 = (Image.open('image.jpeg').convert('L')) 
img1.show()

img = array((Image.open('image.jpeg').convert('L')))
a,b = img.shape #saving the no of rows and col in a tuple
print('nnOriginal image: ')
print(img)
print((a,b))
tup = a,b

for i in range (0, tup[0]):
    for j in range (0, tup[1]):
        img[i][j]= (pow(img[i][j],7)%187)


print('nnEncrypted image: ')
print(img)
imgOut = Image.fromarray(img)
imgOut.show()
imgOut.save('img.bmp')

#decryption

img2 = (Image.open('img.bmp'))
img2.show()
img3 = array(Image.open('img.bmp'))
print('nnEncrypted image: ')
print(img3)
a1,b1 = img3.shape
print((a1,b1))
tup1 = a1,b1

for i1 in range (0, tup1[0]):
    for j1 in range (0, tup1[1]):
        img3[i1][j1]= ((pow(img3[i1][j1], 23))%187) 
print('nnDecrypted image: ')
print(img3)
imgOut1 = Image.fromarray(img3)
imgOut1.show()
print(type(img))  
  

Значения матриц:

Исходное изображение:

[[41 42 45 … 47 41 33]

[41 43 45 … 44 38 30]

[41 42 46 … 41 36 30]

[43 43 44 … 56 56 55]

[45 44 45 … 55 55 54]

[46 46 46 … 53 54 54]]

Зашифрованное изображение:

[[ 46 15 122 … 174 46 33]

[ 46 87 122 … 22 47 123]

[ 46 15 7 … 46 9 123]

[ 87 87 22 … 78 78 132]

[122 22 122 … 132 132 164]

[ 7 7 7 … 26 164 164]]

Расшифрованное изображение:

[[136 70 24 … 178 136 164]

[136 111 24 … 146 141 88]

[136 70 96 … 136 100 88]

[111 111 146 … 140 140 1]

[ 24 146 24 … 1 1 81]

[ 96 96 96 … 52 81 81]]

Любая помощь будет высоко оценена. Спасибо.

Комментарии:

1. Странно, что вы получаете 46 в качестве зашифрованного значения, потому что ваше исходное изображение должно иметь dtype uint8 и pow(np.uint8(41),7)7 вычисляется как 86 , не 46 .

2. Тогда как решить проблему?

3. Я не могу даже воспроизвести проблему, не говоря уже о ее решении. Я получаю 86 вместо 46 в зашифрованном изображении, когда запускаю ваш код. Вы уверены, что получаете 46?

4. да, я почти уверен. кстати, это написано на python 3.7.

5. Тогда я в растерянности. Можете ли вы предоставить образец изображения?

Ответ №1:

Я думаю, вы справитесь лучше, используя 3-й параметр pow() функции, которая выполняет модуль внутри для вас.

Вот небольшой пример без сложности загрузки изображений — просто представьте, что это градиент в оттенках серого от черного к белому.

 # Make single row greyscale gradient from 0..255
img = [ x for x in range(256) ]

# Create encrypted version
enc = [ pow(x,7,187) for x in img ]

# Decrypt back to plaintext
dec = [ pow(x,23,187) for x in enc ]
  

Кажется, что оно расшифровывается обратно в исходные значения с 0 .. 187, где все идет не так — предположительно, из-за переполнения? Может быть, кто-то умнее меня сможет это объяснить — пожалуйста, добавьте комментарий для меня, если вы знаете!

Комментарии:

1. Это не будет работать в этом скрипте, поскольку img[i][j] является numpy.ndarray и для использования 3-го параметра pow() мне нужно, чтобы все параметры были как int

2. Чтобы это сработало, мне нужно перевести каждое значение img в int тип данных типа temp , подобный, тогда только я могу использовать это.

3. Вы можете легко преобразовать массив Numpy в список с помощью img.tolist() Однако, я хочу использовать 3-й параметр, чтобы pow() не заставлять вас использовать список.