You are on page 1of 6

#!

/usr/bin/env python
# -*- coding: UTF-8 -*import easygui,wave
import os, random, struct
from Crypto.Cipher import AES
from Tkinter import Tk
from tkFileDialog import askopenfilename
Tk().withdraw() # we don't want a full GUI, so keep the root window from appeari
ng
#filename = askopenfilename() # show an "Open" dialog
def encrypt_file(key, in_filename, out_filename=None, chunksize=64*1024):
""" Encrypts a file using AES (CBC mode) with the
given key.
key:
The encryption key - a string that must be
either 16, 24 or 32 bytes long. Longer keys
are more secure.
in_filename:
Name of the input file
out_filename:
If None, '<in_filename>.enc' will be used.
chunksize:
Sets the size of the chunk which the function
uses to read and encrypt the file. Larger chunk
sizes can be faster for some files and machines.
chunksize must be divisible by 16.
"""
if not out_filename:
out_filename = in_filename + '.w'
iv = ''.join(chr(random.randint(0, 0xFF)) for i in range(16))
encryptor = AES.new(key, AES.MODE_CBC, iv)
filesize = os.path.getsize(in_filename)
with open(in_filename, 'rb') as infile:
with open(out_filename, 'wb') as outfile:
outfile.write(struct.pack('<Q', filesize))
outfile.write(iv)
while True:
chunk = infile.read(chunksize)
if len(chunk) == 0:
break
elif len(chunk) % 16 != 0:
chunk += ' ' * (16 - len(chunk) % 16)
outfile.write(encryptor.encrypt(chunk))
return out_filename
def decrypt_file(key, in_filename, out_filename=None, chunksize=24*1024):
""" Decrypts a file using AES (CBC mode) with the
given key. Parameters are similar to encrypt_file,
with one difference: out_filename, if not supplied
will be in_filename without its last extension
(i.e. if in_filename is 'aaa.zip.enc' then

out_filename will be 'aaa.zip')


"""
if not out_filename:
out_filename = os.path.splitext(pathFileWav)[0]
with open(in_filename, 'rb') as infile:
origsize = struct.unpack('<Q', infile.read(struct.calcsize('Q')))[0]
iv = infile.read(16)
decryptor = AES.new(key, AES.MODE_CBC, iv)
with open(out_filename, 'wb') as outfile:
while True:
chunk = infile.read(chunksize)
if len(chunk) == 0:
break
outfile.write(decryptor.decrypt(chunk))
outfile.truncate(origsize)
ke = easygui.passwordbox('contrasena para cifrar o descifrar') # clave de cifra
do en caso de haberlo activado
if len(ke) <32 :
while len(ke) < 32 :
ke = ke + "p"
elif len(ke) >32:
ke = ke[:32]
else :
ke = ke
# constantes cifrado
CIPHER_ON = 1 # cifrado activo
CIPHER_OFF = 0 # cifrado inactivo
# variables modificables a gusto
jumpsData = 10 #Espacio de muestras del framerate para la toma de datos vlidos
numFraSize = 4 # 32bits para determinar cuantos bytes ocupa el fichero oculto
header = ["S", "Y", "L", "M"] # 1 byte por cada caracter (contra menos caractere
s, ms posibilidades de error por accidente)
passphrase_cipher = ke
cipher = CIPHER_OFF
msg1 ="que hacemos?"
title1 = "eleccion"
choices = ["codificar", "descodificar"]
choice1= easygui.choicebox(msg1, title1, choices)
if choice1 == "descodificar":
# DATOS DEL USUARIO:
pathFileWav = askopenfilename(title = "selecciona archivo wav a decodificar"
)
sizeFileToHide = 0
sizeFileWav = 0
# Abrimos el archivo WAV que oculta algo
fileAudioBase = wave.open(pathFileWav,'rb')
bytesFileAudioBase = bytearray(fileAudioBase.readframes(fileAudioBase.getnfr
ames()))

channels = fileAudioBase.getnchannels() # canales de audio


sampleWidth = fileAudioBase.getsampwidth() # nmero de bytes para las muestras
del samplerate
frameRate = fileAudioBase.getframerate()
numTotalFrames = fileAudioBase.getnframes()
startIn = 0
indexHeader = 0
indexSampleWav = startIn
saltos = (sampleWidth * jumpsData)
bytesFileOculto = []
indexFileOculto = 0
error = 0
# Leemos cabecera:
for i in range(len(header)):
#bytesFileOculto.append(bytesFileAudioBase[indexSampleWav])
#indexFileOculto += 1
print header[i], chr(bytesFileAudioBase[indexSampleWav])
if header[i] != chr(bytesFileAudioBase[indexSampleWav]):
error = 1
print "Cabecera no vlida"
exit(error)
indexSampleWav += saltos
print "Cabecera vlida (OK!)"
# Leemos el tipo de cifrado que utilizar el fichero resultante:
typeCipher = bytesFileAudioBase[indexSampleWav]
indexSampleWav += saltos
listTamanio = []
# Leemos los bytes que determinan el tamao en bytes del fichero:
for i in range(numFraSize):
listTamanio.append(bytesFileAudioBase[indexSampleWav])
indexSampleWav += saltos
print "Bytes tamao fichero oculto: ", listTamanio
listTamanio.reverse()
print "Bytes tamao reordenados: ", listTamanio
desplazamiento = 0
tamanio = ""
for i in range(numFraSize):
#tamanio += bin(listTamanio[i] & 0xFF)[2:]
listTamanio[i]>>desplazamiento
tamanio += bin(listTamanio[i] & 0xFF)[2:].zfill(8)
print "byte: ", bin(listTamanio[i])[2:].zfill(8)
desplazamiento += 8
sizeFileHidden = int(tamanio, 2)
print "Bytes ocultos: ", sizeFileHidden
bytesFileOculto = []

indexDataHidden = 0
while indexDataHidden < sizeFileHidden:
bytesFileOculto.append(bytesFileAudioBase[indexSampleWav])
indexSampleWav += saltos
indexDataHidden += 1
nameFileResult = "pepe"
ficheroRecuperado = open(nameFileResult, 'wb')
newFileByteArray = bytearray(bytesFileOculto)
ficheroRecuperado.write(newFileByteArray)
ficheroRecuperado.close()
decrypt_file(ke,"pepe")
#os.remove("recuperado.cip")
easygui.textbox("hecho , archivo decodificado nombre recuperado")
os.remove("pepe")
else :
in_file= askopenfilename(title = "selecciona archivo a ocultar") # show an "
Open" dialog
pathFileToHide = encrypt_file(ke,in_file)
#cantidad = float(input("Dgame una cantidad en euros (hasta con 2 decimales):
"))
# DATOS DE LOS FICHEROS NECESARIOS:
#pathFileToHideCipher = pathFileToHide + ".cipher"
pathFileWav = askopenfilename(title = "selecciona archivo wav para ocultacio
n")
pathFileWavResult = pathFileToHide + 'av' # nombre de fichero de salida (el
que ocultar el contenido)

#
# COMPOSICIN DE LA TRAMA DE DATOS OCULTOS:
#
# (CABECERA)->(CIFRADO)->(TAMAO ARCHIVO)->(BYTES ARCHIVO)
#
#TRATANDO CON LOS FICHEROS:
# FICHERO BASE WAV DONDE LO VAMOS A OCULTAR
fileWav = wave.open(pathFileWav,'rb')
bytesfileWav = bytearray(fileWav.readframes(fileWav.getnframes())) # guardam
os los bytes (del muestreo) en un array de bytes
channels = fileWav.getnchannels() # canales de audio (1 mono, 2 stereo)
sampleWidth = fileWav.getsampwidth() # nmero de bytes para las muestras del s
amplerate
frameRate = fileWav.getframerate() # obtenemos el nmero de muestras (frames)
por segundo que realiza
numTotalFrames = fileWav.getnframes() # obtenemos el nmero total de muestras
disponibles (frames)

# calculamos el nmero total de bytes que se puede almacenar:


bytesMaximos = ((numTotalFrames / sampleWidth) / jumpsData) - len(header) 1 # el -1 es para evitar Bytes hurfanos
# mostramos la informacin por pantalla:
print "Nmero de canales: ",channels
print "Ancho de muestra del sample (bytes): ",sampleWidth
print "Nmero de frames totales: ", numTotalFrames
print "Capacidad mxima de almacenado: ", bytesMaximos, "Bytes (",float(bytesM
aximos / 1024), "KBytes )"

# FICHERO QUE QUEREMOS OCULTAR


try:
fileToHide = open(pathFileToHide,'rb')
except:
print "ERROR: problema con fichero"
exit(1)
bytesFileToHide = bytearray(fileToHide.read()) # guardamos todos los bytes d
el archivo en un array
#fileToHide.close()
# comprobamos que el archivo de audio tenga capacidad para esconder el fiche
ro:
if len(bytesFileToHide) < bytesMaximos:
easygui.textbox( "El archivo a ocultar cabe, ok")
else:
easygui.textbox( "El archivo a ocultar no cabe, elige uno menor o un wav
mayor")
exit(1)
startIn = 0 # byte del sample de audio donde se empieza a contar
# A tener en cuenta:
#
# bytem = byte menos significativo
# byteM = byte ms significativo
#
# si se un sistema estereo el muestreo comienza as -> bytem_ch1 - byteM_ch1 bytem_ch2 - byteM_ch2 .....
# si se un sistema mono el muestreo comienza as -> bytem_ch1 - byteM_ch1 - by
tem_ch1 - byteM_ch1 .....
#
# ---------------indexHeader = 0
indexFileToHide = 0
indexSampleWav = startIn
jump = (sampleWidth * jumpsData) # salto para grabar en los bytes correctos
# grabamos la cabecera
while indexHeader < len(header):
bytesfileWav[indexSampleWav] = header[indexHeader]
indexHeader += 1
indexSampleWav += jump
# grabamos el valor de cifrado

bytesfileWav[indexSampleWav] = cipher
indexSampleWav += jump
# grabamos el tamao bytes que ocupa el fichero oculto en los bytes asignados
para ello
# utilizamos desplazamiento de bits para guardarlo en bloques de un octeto (
byte) y luego poder recomponerlo
desplazamiento = 0
for i in range(numFraSize):
#print bytes(len(bytesFileToHide)>>24 & 0xFF) , bytes(len(bytesFileToHid
e)>>16 & 0xFF) , bytes(len(bytesFileToHide)>>8 & 0xFF) , bytes(len(bytesFileToHi
de)>>0 & 0xFF)
bytesfileWav[indexSampleWav] = len(bytesFileToHide)>>desplazamiento & 0x
FF
desplazamiento += 8
indexSampleWav += jump
# grabamos los bytes del archivo oculto en el audio
while indexFileToHide < len(bytesFileToHide):
bytesfileWav[indexSampleWav] = bytesFileToHide[indexFileToHide]
indexSampleWav += jump
indexFileToHide += 1
print indexFileToHide
# GRABAMOS EL FICHERO DE AUDIO RESULTANTE:
outEstegoWAV = wave.open(pathFileWavResult, "wb")
outEstegoWAV.setnchannels(channels)
outEstegoWAV.setsampwidth(sampleWidth)
outEstegoWAV.setframerate(frameRate)
outEstegoWAV.writeframes(bytesfileWav)
outEstegoWAV.close()
easygui.textbox("hecho , archivo codificado junto al original")
fileToHide.close()
os.remove(pathFileToHide)

You might also like