Trying to encrypt video frames with RSA; getting garbage instead of original data after decrypting

一曲冷凌霜 提交于 2020-01-15 05:40:08

问题


I am writing a script to encrypt and decrypt video using RSA algo in python. Now I have extracted the frames from the video and encrypt each image individually and then combining the images to create a video. Then I am reading the frames of the encrypted video again and when I am applying the decryption key I am not getting back the original image. But when I am applying the same key on any image with which the video is made I am getting back the original image. let us say we have image1 which is encrypted and will be used to make the encrypted video when I am applying the key on this image I am getting back the original image. now I have image2 which is read from the encrypted video and if the keys are applied then it is giving a more encrypted image. Heres the code :


import cv2
import numpy
import os
import imageio 
import time
from tkinter.filedialog import askopenfilename
from tkinter.ttk import *
from tkinter import *
from tkinter import filedialog
from tqdm import tqdm 
from tkinter import messagebox
import subprocess


def load_image_decrypt(folder):

    videofile = 'envid.avi'

    try:
        if not os.path.exists('Dedata'):
            os.makedirs('Dedata')
    except OSError:
        messagebox.showinfo('Error Occured', 'Error: Creating directory of decrypted data')

    vid_to_image(videofile)

    for filename1 in tqdm(os.listdir(folder)):
        imgV = imageio.imread(os.path.join(folder, filename1), format='PNG-FI')
        if imgV is not None:
            RGBdecryption(imgV, filename1)
        else:
            break

    vidname = 'devid.avi'
    image_to_vid(dedata2, vidname)

    messagebox.showinfo('Finish!', 'Decryption Done succesfully!')


def RGBdecryption(img, filename):

    img1 = img
    img = img.astype(numpy.uint16)
    img1= img1.tolist()

    for i1 in tqdm(range(len(img1))):
        for j1 in (range(len(img1[i1]))):
            for k1 in (range(len(img1[i1][j1]))):
                x1 = img1[i1][j1][k1] 
                x1 = pow(x1,16971,25777)
                img1[i1][j1][k1] = x1

    img1 = numpy.array(img1).astype(numpy.uint16)
    name = './Dedata/'+str(filename)
    imageio.imwrite(name, img1, format='PNG-FI')

def vid_to_image(filename):
    # Playing video from file:
    cap = cv2.VideoCapture(filename)

    try:
        if not os.path.exists('data'):
            os.makedirs('data')
        messagebox.showinfo('Info!', 'Data directory is created where the frames are stored')

    except OSError:
            print ('Error: Creating directory of data')

    currentFrame = 0
    while(True):
        # Capture frame-by-frame
        ret, frame = cap.read()
        if not ret: 
            break

        # Saves image of the current frame in jpg file
        name = './data/frame' + str(currentFrame) + '.png'
        print ('Creating...' + name)
        imageio.imwrite(name, frame,format='PNG-FI')

        # To stop duplicate images
        currentFrame += 1

    # When everything done, release the capture
    cap.release()
    cv2.destroyAllWindows()


def image_to_vid(folder, vidname):  #the code which is creating a video out of images stored in the folder

    image_folder = folder
    video_name = vidname
    sort_image = []
    images = [img for img in os.listdir(image_folder) if img.endswith(".png")]
    print(images)
    print('\n\n')

    for i in range(0,1000):
        for j in range(len(images)):
            name = 'frame' + str(i) + '.png' 
            if ((str(images[j])) == str(name)):
                sort_image.append(images[j])

    print(sort_image)
    frame = cv2.imread(os.path.join(image_folder, sort_image[0]))
    height, width, layers = frame.shape

    video = cv2.VideoWriter(video_name, 0, 29, (width,height)) #29 is the fs of the original video and I don't know what the 0 is for

    for image in sort_image:
        video.write(cv2.imread(os.path.join(image_folder, image)))

    cv2.destroyAllWindows()
    video.release() 


data = './data'
load_image_decrypt(data)

I do not know where I am getting it wrong. I am new to opencv and video processing. Any help will be appreciated. Thank you.


回答1:


Video frames are subject to lossy compression. So you cannot feed a codec some binary data under the guise of images, encode it and expect to get exactly the same binary data back when playing the resulting video.

Your best bet is to encrypt the video file as a whole as per Encryption of video files? or How can I Encrypt Video in Real Time?. It will need to be decrypted to be playable; this is apparently what OSX's "content protection" does, encrypting and decrypting data transparently.

A (paywalled) IEEE article Video Encryption Based on OpenCV - IEEE Conference Publication says they applied an Arnold Transform to image data. It is a transposition cipher and as such, can be broken. Its main strength seems to rather be that it makes content unintelligible in regular playback, and it preserves image characteristics critical for video codecs (lighting, frame differences) and doesn't require the exact ciphertext for decryption, so it's not damaged beyond repair by the lossy compression.



来源:https://stackoverflow.com/questions/55654976/trying-to-encrypt-video-frames-with-rsa-getting-garbage-instead-of-original-dat

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!