WIP: adding jpg image processing support

This commit is contained in:
JohnE 2016-08-30 02:30:42 -07:00
parent fa47d213cb
commit d039f2a9e6
5 changed files with 158 additions and 35 deletions

View File

@ -8,10 +8,9 @@ from Crypto.Hash import SHA512
class Signature:
signature = None
key_data = None
pub_key = None
priv_key = None
sig_data = None
#
def __init__(self):
@ -21,9 +20,9 @@ class Signature:
def genSig(self, bin_data):
hshh = SHA512.new()
hshh.update(bin_data)
signer = PKCS1_v1_5.new(self.priv_key)
self.signature = signer.sign(hshh)
return self.signature
signer = PKCS1_v1_5.new(self.key_data)
self.sig_data = signer.sign(hshh)
return self.sig_data
#
def verifySig(self, bin_data, bin_sig):
@ -35,16 +34,23 @@ class Signature:
#
def genKeys(self):
logging.info("Generating public keys...")
self.key_data = RSA.generate(4096)
self.pub_key = RSA.importKey( self.key_data.publickey().exportKey('DER'))
self.priv_key = RSA.importKey( self.key_data.exportKey('DER'))
logging.debug(self.pub_key.exportKey('PEM'))
logging.debug(self.priv_key.exportKey('PEM'))
self.key_data = RSA.generate(4096)
self.pub_key = self.key_data.publickey()
logging.debug("public key==\n{}".format(self.pub_key.exportKey('PEM')))
logging.debug("private key (and pub, other info)==\n{}".format(self.key_data.exportKey('PEM')))
#
def getKeyPEM(self):
def getPrivKeyPEM(self):
return self.key_data.exportKey('PEM')
#
def getPubKeyPEM(self):
return self.pub_key.exportKey('PEM')
#
def getSignature(self):
return sig_data
#
def hashBin(self, bin_data):
hshh = SHA512.new()

View File

@ -2,43 +2,79 @@
#
#
import logging
import json
import gi
gi.require_version('GExiv2', '0.10')
from gi.repository import GExiv2
#
# { 'pub_key':b"\x8f\xab\xfe\xd1\xd5\xb4\xea\xbb\xfa", 'sig':b"\x8f\xab\xfe\xd1\xd5\xb4\xea\xbb\xfa" }
#
#
class ImgExif:
sig_h = None
exif_c = None
img_fn = None
#
def __init__(self):
self.exif = None
self.img_fn = None
self.img_loaded = False
def __init__(self, img_fn):
self.useImg(img_fn)
#
def useImg(self, img_fn):
result = False
try:
self.exif = GExiv2.Metadata()
ret = self.exif.open_path(img_fn)
self.exif_c = GExiv2.Metadata()
ret = self.exif_c.open_path(img_fn)
if (ret):
result = True
self.img_loaded = True
except Exception as ex:
logging.error(ex)
raise
self.img_fn = img_fn
self.sig_h = {}
#
def appendKey(self, key):
logging.info('Adding key to metadata...')
self.exif.set_comment(str(key.getKeyPEM()))
def addKey(self, key):
self.sig_h['pub_key'] = key
#
def addSig(self, sig):
self.sig_h['sig'] = sig
#
def toJSON(self):
return json.dumps(self.sig_h)
#
def extractKey(self):
pemData = self.exif.get_comment()
pemData = self.exif_c.get_comment()
#
def saveFile(self):
logging.info("Saving image as {}...".format(self.img_fn))
self.exif.save_file(self.img_fn)
self.exif_c.set_comment(json.dumps(self.sig_h))
self.exif_c.save_file(self.img_fn)
#
def saveAsFile(self, fn):
#fn = self.img_fn + "_PICSEAL.jpg"
logging.info("Saving image as {}...".format(fn))
self.exif_c.set_comment(json.dumps(self.sig_h))
self.exif_c.save_file(fn)
#
# TESTING
#
#
def _test():
img = ImgExif("test/bmw_rim_640_backup.jpg")
img.addKey("-/-THIS IS A KEY-/-")
img.addSig("-/-THIS IS A SIG-/-")
print("JSON: \n{}".format(img.toJSON()))
img.saveFile()
if __name__ == '__main__':
_test()

View File

@ -3,13 +3,81 @@
#
from PIL import Image
#
# 0xFF,0xD8 - Start of Image
# 0xFF,0xEn - App Exif data
# 0xFF,0xD8 - DQT - Define Quantization Table
# 0xFF,0xDD - DRI - Define Restart Interval
# 0xFF,0xFE - Comments
# 0xFF,0xC0 - SOF0 - Start of Frame
# 0xFF,0xC2 - SOF2 - Start of Frame
# 0xFF,0xC4 - DHT - Define Huffman Tables
# 0xFF,0xDA - SOS - Start of Scan
# 0xFF,0xDn - RST - Restart (n=0..7)
# 0xFF,0xEn - Application
# 0xFF,0xD9
#
#
# https://en.wikipedia.org/wiki/JPEG
class JpgTools:
BUF_CHUNK_SIZE = 2048
data_buf = None
data_idx = None
fh = None
def __init__(self):
pass
#
def process(self, fname):
def jpgHash(self):
def findMarkers(self):
last_idx = len(self.data_buf)
while
while ord(self.data_buf[self.data_idx]) != 0xFF:
self.data_idx = self.data_idx+1
for idx in range(last_idx):
while self.data_buf:
self.getBytes
pass
def processFile(self, fname):
self.data_buf = self.fh.read(self.BUF_CHUNK_SIZE)
while self.data_buf:
(ret, fin) = self.findMarkers()
#
def getBytes(self, fname):
if (not self.fh):
self.fh = open(fname, "rb")
self.data_buf = self.fh.read(self.BUF_CHUNK_SIZE)
def processFile(self, fname):
self.fh = open(fname, "rb")
self.data_buf = self.fh.read(self.BUF_CHUNK_SIZE)
if (self.data_buf):
self.data_idx = 0
findMarkers()
#
def process_OLD(self, fname):
Image.open(fname)
# image as a sequence object containing pixel values
bin_data = list( im.getdata() )
@ -17,7 +85,8 @@ class JpgTools:
im.tostring()
#
def getJpgBin(self, fname):
def getJpgBin_OLD(self, fname):
img_h = Image.open(fname)
img_bin = list(img_h.getdata())
return img_bin

View File

@ -20,20 +20,32 @@ def main():
# create new pub keys, sign hash
# export signature & public key to a new image file
def processImage(image_fn):
jpg = JpgTools()
img_bin = jpg.getJpgBin(image_fn)
sig = Signature()
sig.genSig(img_bin)
(pub_fn, priv_fn) = copyImage(image_fn)
getHash
addSignature(new_fn)
writePubImg(pub_fn, sig)
writePrivImg(priv_fn, sig)
# add a digital signature to the metadata
def addSignature(image_fn):
img = ImgExif()
img.useImg(image_fn)
key = Signature()
img.appendKey(key)
def writePubImg(pub_fn, sig):
img = ImgExif(pub_fn)
img.addKey(sig.getPubKeyPEM())
img.addSig(sig.sig_data)
img.saveFile()
#
def writePrivImg(priv_fn, sig):
img = ImgExif(priv_fn)
img.addKey(sig.getPrivKeyPEM())
#img.addSig(sig.sig_data)
img.saveFile()
#
def copyImage(image_fn):
basename = os.path.basename(image_fn)
(filename, ext) = Toolbox.parseFilenameIncExt(basename)

View File

@ -1,5 +1,5 @@
#
#
# Test Signature Class
#
from ..libs.crypto_pub import Signature