python-3.ximageencryptionxorbitwise-xor

Searching for a way to do Bitwise xor on images with keys


I am looking for way to encrypt images with keys, first input should be image like this: input

Second input look like this: key = "01010100 01110010 10101110 01110001 10110000 01100001 01010010 10110001 10110011 10110011 10000000 01011100 01010010 01011100 11010011 00011000 10100100"(or i can convert this to another type but this is my raw data)

And after xor image^key output should look like this:

output

What i've tried so far ?

import cv2
import numpy as np
 
demo = cv2.imread("koala.jpeg")
key = "01010100 01110010 10101110 01110001 10110000 01100001 01010010 10110001 10110011 10110011 10000000 01011100 01010010 01011100 11010011 00011000 10100100"
r, c, t = demo.shape

 

 
 
encryption = cv2.bitwise_xor(demo, key) # encryption
decryption = cv2.bitwise_xor(encryption, key) # decryption
 
cv2.imshow("encryption", encryption) # Display ciphertext image
cv2.imshow("decryption", decryption) # Display the decrypted image
 
cv2.waitKey(-1)
cv2.destroyAllWindows()

Here is the output:

Traceback (most recent call last):
  File "/Users/kemal/Documents/Python/pyImage/xor.py", line 10, in <module>
    encryption = cv2.bitwise_xor(demo, key) # encryption
TypeError: Expected Ptr<cv::UMat> for argument 'src2'

My question is, what is the proper way to xor my image and my key?

Now i've achieve success encryption with two images but when want to encrypt my image with a key its not working.

Actually i know this is the wrong way to do this encryption, maybe i can try to convert my key to image but i believe there is a proper way to do this, and i want to learn. Thank you for any kind of help.

If this library is not a proper way to do this encryption i can also change library and use different library there is no restrictions. Only important thing is input and outputs for me.

Thank you for any kind of help.


Solution

  • The following Python program:

    enter image description here

    enter image description here

    enter image description here

    Please note, that depending on the size of the image, each encryption and decryption can take a few seconds.

    import cv2
    import numpy as np
    from numpy import random
    
    # Load original image
    demo = cv2.imread(<path to jpeg>)
    r, c, t = demo.shape
    
    # Display original image
    cv2.imshow("Original image", demo)
    cv2.waitKey()
    
    # Create random key
    key = random.randint(256, size = (r, c, t))
    
    # Encryption
    # Iterate over the image
    encrypted_image = np.zeros((r, c, t), np.uint8)
    for row in range(r):
        for column in range(c):
            for depth in range(t):
                encrypted_image[row, column, depth] = demo[row, column, depth] ^ key[row, column, depth] 
                
    cv2.imshow("Encrypted image", encrypted_image)
    cv2.waitKey()
    
    # Decryption
    # Iterate over the encrypted image
    decrypted_image = np.zeros((r, c, t), np.uint8)
    for row in range(r):
        for column in range(c):
            for depth in range(t):
                decrypted_image[row, column, depth] = encrypted_image[row, column, depth] ^ key[row, column, depth] 
                
    cv2.imshow("Decrypted Image", decrypted_image)
    
    cv2.waitKey()
    cv2.destroyAllWindows()
    

    After loading, the original image is stored in a 3D array with r rows, c columns and t color values between 0 and 255.
    Next, a key is generated that corresponds to an identically sized array whose elements are randomly generated.
    For encryption, it is iterated over the original image and each value of the image array ix XORed with the corresponding value of the key array.
    For decryption, an analogous iteration is performed over the encrypted image and each value of the encrypted image array is XORed with the corresponding value of the key array.

    Please note that this logic is not to be considered as the right way, but as a possible one. It is based on a one-time-pad encryption, which is information-theoretically secure when used as specified. However, this is not fulfilled here, since the key would have to be chosen truly randomly, whereas here it is chosen pseudo randomly. For a one-time-pad, the key has to be as long as the message, i.e. the key array has to be as large as the image data. In principle, other algorithms can be used as well, e.g. AES, wich is however more complex to implement (with regard to padding, IV etc.).

    Note also that when storing the encrypted image, a format must be used that does not change the image data (which is actually the ciphertext). Otherwise, after loading the encrypted image, decryption may be incorrect or even impossible, depending on the algorithm. A format that generally compresses the data and thus changes the data is e.g. jpg, a format that does not change the data is e.g. bmp, see e.g. here for more details. The format can be controlled by the file extension when saving with imwrite.