Compresión y encriptación asimétrica mediante GPG: sfxcompress

jactamayo
  13 years ago
  0

En la entrada que hablamos sobre el compresor que genera ficheros autoextraibles, explicamos la manera de generar dichos ficheros mediante un script de shell.

A este tipo de ficheros podemos añadir una nueva característica: encriptación asimétrica. La criptografía asimétrica es el método criptográfico que usa un par de claves para el almacenamiento o envío de información: una denominada pública y otra privada. La clave pública se puede entregar a cualquier persona y la privada debe mantenerse en secreto, de modo que con este método se encripta con la clave pública y se desencripta con la privada. Uno de los programas que se encarga de esta tarea es el denominado GNU Privacy Guard (GPG), pero existen otros, por ejemplo: DSA, PGP, SSH, SSL y TLS.

El objetivo del script de shell es simplificar las opciones a utilizar y generar ficheros comprimidos, encriptados y auto-extraibles, de modo que se facilite su uso. Para ello partimos del código explicado en la entrada mencionada.

Primero, dado que el número de opciones ha aumentado, es necesario tratar los parámetros de entrada de manera más cuidadosa. Se va a definir las siguientes opciones:

Opción Parámetro Descripción
-f filename Indica el nombre base del fichero de salida y su path.
-g   Indica que se utilice compresión gzip.
-b   Indica que se utilice compresión bzip2 (es la opción por defecto).
-k   Indica que debe encriptarse el fichero de salida.
-h   Muestra las opciones
-v   Muestra la versión del programa y la licencia

Como se observa, se ha definido los parámetros como los estándares de UNIX: opciones de una sola letra con un guión delante.

Para hacer el análisis de los parámetros de entrada, se utiliza el siguiente bucle:

# Parse the parameters
while getopts  ":bf:ghkv" flag
do
        chooseOptions $flag "$OPTARG"
done

Donde la función chooseOptions recibe cada parámetro y asigna las variables necesarias antes de la compresión:

# function name: chooseOptions, the function shows by screen the version of the program
#    parameters: - the valid option (b, f, g, h, k, or v)
#                - the parameter needed, for instance "f" needs the filename
function chooseOptions {

        if [ "$1" = "g" ]; then
                compresor="z"
                extension="tgz"
        else
        if [ "$1" = "b" ]; then
                compressorByDefault
        else
        if [ "$1" = "k" ]; then
                encriptar="si"
        else
        if [ "$1" = "f" ]; then
                filename="$2"
        else
        if [ "$1" = "h" ]; then
                syntax
        else
        if [ "$1" = "v" ]; then
                version
        else
                echo "ERROR: \"$2\" is an invalid option."
                echo
                exit -1
        fi
        fi
        fi
        fi
        fi
        fi

} # chooseOptions

Si todo es correcto, el programa llama a la función compress que se encarga de comprimir (y encriptar) el fichero de salida. Es importante señalar que la compresión se hace en la memoria de tal forma que no se generan ficheros intermedios que puedan comprometer información sensible. Primero comprueba si existe el fichero ".exclude" que indica los ficheros que deben ignorarse, por ejemplo, en ciertas circunstancias puede ser interesante ignorar los ficheros que terminen en '~': "*~".

# function name: compress, the main function of the program
#    parameters: - the base name
function compress {

        compressed=$(mktemp -t XXXXXXXXXXXXXXXX)
        encrypted=$(mktemp -t XXXXXXXXXXXXXXXX)
        # If .exclude exists, then the program must be work with it
        if [ -f ".exclude" ] ; then
                excluded=$(mktemp -t XXXXXXXXXXXXXXXX)
                echo >$excluded
                for i in $( cat .exclude ); do
                        find . -name "$i" >>$excluded
                done
                if [ "$encriptar" = si ]; then
                        rm -f $encrypted
                        tar cvX$compresor $excluded . | gpg -o $encrypted --encrypt
                else
                        tar cvXf$compresor $excluded $encrypted .
                fi
        else
                if [ "$encriptar" = si ]; then
                        rm -f $encrypted
                        tar cv$compresor . | gpg -o $encrypted --encrypt
                else
                        tar cvf$compresor $encrypted .
                fi
        fi
        # The compressed (and encrypted) file has been created

        # The last step is to encapsulate all in a self-extracting style bash-script
        comp=$(mktemp -t XXXXXXXXXXXXXXXX)
        SIZE=$(cat $encrypted | wc -c)
        SALIDA="$1.$extension.sfx"
        echo "#!/bin/bash" >$comp
        echo "">>$comp
        echo "SIZE=\"$SIZE\"">>$comp
        echo "compresor=\"$compresor\"">>$comp
        echo "filename=\"$(basename "$1")\"">>$comp
        echo "extension=\"$extension\"">>$comp
        echo "fecha=\"$(date)\"">>$comp
        echo "mdf=\"$(cat $encrypted | md5)\"">>$comp
        if [ "$encriptar" = si ]; then
                echo "encriptado=\"$encriptar\"">>$comp
                echo "adjetive=\" encrypted\"">>$comp
        fi
        # Take care!, the parameter in tail indicates the start of
        # the second part of the script, do not modify unless you
        # know what you do.
        cat "$0" | tail -39 >>$comp
        cat $encrypted >>$comp
        chmod 755 $comp
        # Delete temporary files
        rm -f $compressed
        rm -f $excluded
        rm -f $encrypted
        mv $comp "$SALIDA"
        echo
        echo The file $SALIDA has been created.
        echo

} # compress

Para ver el código completo y descargarlo, puede dirigirse a la página oficial, alojada en SourceForge.