Archive for julio, 2012

Generación de Hashes en Objective-C

Actualmente dentro de los “frentes abiertos” que tengo está el de hacer un “port” de una aplicación que desarrolle para la empresa en la que trabajo de .NET a IOS.

Dicha aplicación tiene un gestor de perfiles de usuario que pueden guardar sus contraseñas y otros datos sensibles de manera segura.

Una aplicación de este tipo tiene unas particularidades con los que no me había encontrado hasta ahora en un proyecto de IOS, se trata de la generación de “Hashes” y el cifrado/descifrado de datos.

Mis ideas tenia de cómo tenia que atacar dicho proyecto, pero algunas eran un poco descabelladas…y todo por evitar tocar las clases se seguridad nativas de Objective-C que se planteaban como bastante densas…

Siguiendo los consejos de un par de cracks como Rafa Aguilar y Fernando Rodríguez encauce las búsquedas por otro lado, y decidí documentar el proceso por si a alguien podía servirle todo este meollo… ;)

En este primer post tocaremos la problemática de la generación de un Hash seguro.

La idea básica de un valor hash es que sirva para representar de una manera compacta de la cadena de entrada. Las funciones Hash se utilizan para multitud de cosas… por ejemplo para verificar que dos archivos sean exactamente iguales (el famoso CheckSum), o para lo que vamos a usarla, para comparar dos passwords uno de los cuales estará ya bajo la forma de Hash. Uno de los Hash mas utilizados en entornos web es el MD5, que ha tenido polémica últimamente a causa de una pruebas de colisiones (se dice cuando dos inputs diferentes pueden generar un mismo output) que no lo han dejado en buen lugar. Incluso existen bases de datos con hashes ya generados de listas de passwords, que mucha gente usa para hacer ataques de fuerza bruta…así que de momento vamos a olvidarnos de MD5… ;)

No olvidéis que un hash no es una función de cifrado, y no debe ser usado para “guardar datos”, por varias razones, pero lo mas importante…no es reversible…así que  lo usamos solo para comparar, ok? ;)

Nosotros este Hash tenemos pensado usarlo para acceder a la app, para el resto de datos usaremos AES (aunque eso lo tocaremos en otro post)…solo lo usaremos para comprobar si tienes autorización para acceder a la App…

La elección del Hash que os propongo es SHA512, el uso de cualquier otra versión de SHA anterior, o el uso de MD5 para estos menesteres deberá ser motivo de penitencia y auto-fustigación por el mero hecho de haberlo pensado…Existe mucha documentación de porque usar el uno o el otro, solo os resumo que actualmente el uso de SHA512 es el aconsejado para estos menesteres… ;)

Genial, tenemos la elección del algoritmo hecha, y ahora como la integramos en el proyecto?

Una opción sencilla es el uso de Categorías en Objective-C, lo que nos permite “ampliar” las posibilidades ofrecidas por una clase anterior.

Podríamos optar por una categoría de NSData, o también de NSString que es por la que me decidí…

Si necesitáis algo mas de información sobre categorías, hice una introducción en un post anterior.

Bien…pues vamos por faena…vamos a crear nuestra categoría de NSString.

Creamos un proyecto, por ejemplo usando un template de una single view, así tendremos un viewController con el que jugar…

Después añadimos un “New File” del tipo “Objective-C Categoría” (esto nos ahorra alguna líneas que typear, vaguete que es uno).

Le damos por nombre Hashes y le decimos que sea una categoría de “NSString”.

Esto nos genera dos archivos, la cabecera “NSString+Hashes.h” y el archivo el cuerpo donde implementar “NSString+Hashes.m”. Como sois muy observadores veréis la nomenclatura que adopta el nombre de la categoría “Categoría que quieres ampliar+tu categoría”. No nos tendremos que olvidar de importar esta en los controladores que lo necesiten para poder funcionar… ;)

Lo que nosotros queremos es ampliar las funcionalidades de NSString para que nos sea mas fácil transformar cadenas a Hashes así que declaramos un par de métodos en “NSString+Hashes.h”

- (NSString *)md5;
- (NSString *)sha512;

La clase importante del sistema que vamos a usar, es “CommonCrypto/CommonDigest” así que la importamos en “NSString+Hashes.m” (sino tu código empezar a fallar como una escopeta de feria).

#import <CommonCrypto/CommonDigest.h>

En este mismo archivo debemos implementar los dos métodos que hemos declarado.

Empezando por el md5 :

- (NSString *)md5
{
    NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
    uint8_t digest[CC_MD5_DIGEST_LENGTH];
    
    CC_MD5(data.bytes, data.length, digest);
    
    NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
    
    for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
    {
        [output appendFormat:@"%02x", digest[i]];
    }
    
    return output;
}

La implementación de este método es un estándar que se usa comúnmente, por ejemplo el SDK de Facebook lo usa, y es que el tema de los Hashes es el pan nuestro de cada día, sobretodo en entornos Web, o en entornos que tengan que lidiar con WebServices…

Lo que hace el método es asegurarse de que la cadena este en UTF8 (ya que el charset es una de las fuentes mas corrientes de errores con los Hash…dando problemas de incongruencias).

Después trabajamos con un array de bytes que generamos y recorremos justo después pasándolo a hexadecimal y creando un bonito churro que es nuestro Hash final…

Otra practica bastante extendida sobretodo si tenemos que pasar esa Hash como parámetro a web o tratar con un Webservice es convertir este churro hexadecimal a Base64…si hay interés también explicare en otro post como podemos hacer esto…

- (NSString *)sha512
{
    NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
    uint8_t digest[CC_SHA512_DIGEST_LENGTH];
    
    CC_SHA512(data.bytes, data.length, digest);
    
    NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA512_DIGEST_LENGTH * 2];
    
    for (int i = 0; i < CC_SHA512_DIGEST_LENGTH; i++)
    {
        [output appendFormat:@"%02x", digest[i]];
    }
    
    return output;
}

Como veréis las diferencias saltan a los ojos, y simplemente leyendo la documentación podremos cambiar el algoritmo fácilmente y usar SHA1, SHA256 etc…aunque los mas corrientes siguen siendo MD5 (a pesar de su mala fama es quizás el mas usado) y SHA512 que esta cogiendo mucha fuerza…

Bueno ahora solo nos queda hacer algo con esto para ver si funciona…

Como hemos creado el proyecto con una plantilla “Single View” tenemos que tener por ahí un ViewController.m ya creado.

Importamos la categoría creada

#import “NSString+Hashes.h”

Y creamos el viewWillAppear (acostumbraros, que dicen que los Load, Unload etc…van a desaparecer dentro de no mucho) para poder poner algo de código en el…

-(void)viewWillAppear:(BOOL)animated{

    NSString *churro = @"Churro Patatero";
    
    NSLog(@"MD5 : %@",[churro md5]);

}

Y con al ejecutar el código se nos retorna este estupendo churro… : “MD5 : 2176861a0ed7f1146549e39c28a3f002″

En teoría la primera vez que se le pide al usuario la contraseña se convierte en un Hash y esta se guarda.

Al volverle a pedir la contraseña convertimos la cadena en un Hash que comparamos con el Hash guardado…eso nos dará acceso o no a la aplicación (o no). Si la app nos concede acceso, usaremos esa cadena para cifrar/descifrar datos…nunca el hash que tenemos ahí…

El Hash te concederá acceso a la app, pero en caso de que alguien accediese a los datos guardados sin la “cadena original” no podrá revertir el proceso…que es lo que esperamos… ;)

Pero de eso hablaremos en otro Post, ya que AES tiene también bastante chicha, y algún que otro problemilla (os presentare al “Apple idioten Vector” xD) bajo IOS que intentare ayudaros a solventar… ;)

Espero que este post haya podido ser de ayuda, es el primero de una lista que tengo preparada así que igual aun tengo que cogerle el tono a como presentar las cosas, como explicarlas, donde recortar y donde explayarme mas…así que ser buenos y criticar de forma constructiva… ;)

Share

Categorias en Objective-C

Durante el desarrollo de una aplicación es muy común necesitar “más” de lo que nos ofrece una clase ya creada. La programación orientada a objetos nos ofrece varias maneras de paliar ese déficit.

Uno muy habitual (sobretodo si vienes del mundo Java) es usar la herencia, donde “heredaríamos” las funcionalidad de esa clase anterior y la extenderíamos implementando nuevos métodos.

Objective-C no usa en exceso esta manera de trabajar, aunque evidentemente tienes múltiples maneras de atajar esas peculiaridades.

Hoy os quería presentar una de ellas : Las categorías.

Las categorías nos permiten hacer cosas como esta :

NSString *cadena = [NSString initWithString:@"Churro Patatero"];
NSLog(@"Veamos que sale: %@", [cadena md5]);

Y nos devolvería esto: “Veamos que sale: 2176861a0ed7f1146549e39c28a3f002”

Evidentemente NSString no viene de serie con un generador de hashes MD5, asi que hemos usado una categoría para proporcionarle fácilmente esa funcionalidad.

Pros del uso de las categorías :

-Nos permiten añadir nuevas funcionalidades a la clase, sin crear una subclase.

-Los usuarios no tienen que construir de nuevo una clase por lo tanto es sencillo adaptarse al código.

-Los métodos declarados en dicha categoría tienen acceso a las variable de instancia de la clase original, mas las que están declaradas en las subclases.

-Permite segmentar tu código, y hacerlo mas claro. Puedes por ejemplo subdividir una clase muy grande con categorías anidadas por funcionalidades.

-Permite ocultar ciertos métodos a los ojos de los desarolladores (al no tenerlos implementados en la interface).

Contras del uso de categorías :

Cualquier developer puede ampliar cualquier clase, y si contamos con que la propia Apple no deja de ampliar y modificar sus propias clases, podemos llegar a la conclusión de que existen serias posibilidades de que algún día existan “colisiones” entre los métodos que nosotros hemos creado y los que alguien haya creado/modificado en la clase original…

Es por ello aconsejado el usar algún tipo de prefijo para evitar sustos futuros…

Pasamos a ver mas como crear una Categoría :

La norma mas habitual para el nombre de la categoría es usar nombre clase a ampliar+nombre de nuestra categoría. Lo que aquí daría algo parecido a esto : NSString+JRDHashes

Y esto nos deja trabajar con dos ficheros NSString+JRDHashes.h y NSString+JRDHashes.m

Para hacer la declaración de la categoría en  NSString+JRDHashes.h :

@interface NSString (JRDHashes)

- (NSString *)md5;
- (NSString *)sha1;
- (NSString *)sha256;
- (NSString *)sha512;

@end

Donde NSString es la clase que queremos ampliar y JRDHashes es el nombre de nuestra categoría.

Y la implementación es igual a la de cualquier otra clase…aunque eso lo veremos mas a fondo tocando justamente el tema Hashes y categorías en otro post.

Share

Convertir UIView a UIImage

Este snippet sirve esencialmente para convertir una UIView (la vista y todo su contenido) en una UIImage…y a partir de ese momento poder hacer con esa imagen lo que queramos…transiciones, transformaciones etc…

Esta aportación a sido hecha por Joan Biscarri de Protect Five, y seguro que encontráis manera de sacarle partido… ;)

+ (UIImage *)getCurrentPageViewAsImagefromView:(UIView*)view

{

    UIImage *pageImage = nil;

    UIGraphicsBeginImageContext(view.bounds.size);

    [view.layer renderInContext:UIGraphicsGetCurrentContext()];

    UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();

    if(viewImage)

    {

        NSData *imageData=UIImagePNGRepresentation(viewImage);

        if(imageData)

        {

            pageImage = [UIImage imageWithData:imageData];

            UIGraphicsEndImageContext();

        }

    }    

    return pageImage;

}
Share

Vb.net – Saltos de linea

Tenemos varias maneras de realizar el salto de linea en VB.net

Utilizando constantes de VB

  • vbNewLine
  • vbCrLf

Utilizanzo la función de caracteres

  • Chr(13)

Utilizando el control de caracteres

  • ControlChars.NewLine
  • ControlChars.CrLf

Utilizando la variable de entorno

  • Environment.NewLine

 

Share