Java – Obtener el hash SHA-256 de una cadena

Para no almacenar las contraseñas de los usuarios, puedes guardar el hash y compararlo en el proceso de inicio de sesión. Existen varios algoritmos que te permiten obtener un hash, aquí mostraré cómo utilizar el SHA-256 en java.

String password="secret";
MessageDigest sha256=MessageDigest.getInstance("SHA-256");
sha256.update(password.getBytes("UTF-8"));
byte[] digest = sha256.digest();
StringBuffer sb=new StringBuffer();
for(int i=0;i<digest.length;i++){
    sb.append(String.format("%02x", digest[i]));
}
String hash=sb.toString(); //2bb80d5...527a25b

En internet hay una función que utiliza el método Integer.toHexString pero ésta no imprime el prefijo 0 (cero) en los número menores a 16, es decir, “0d” lo imprime como “d”; lo que causa una diferencia si lo comparas con el hash generado en la línea de comandos de Linux.

Para generar la cadena en la línea de comandos de linux, ejecuta el siguiente comando

echo -n "secret_password" | sha256sum

es importante el parámetro -n en el comando echo para que no agregué un carácter de salto de línea

Fuentes:
http://stackoverflow.com/questions/3021970/which-sha-256-is-correct-the-java-sha-256-digest-or-the-linux-commandline-tool 

Anuncios

Gwt (Java) – Comparar cadenas

En un proyecto de GWT tenía que comparar 2 cadenas para determinar que módulo debía lanzar. Inocentemente -y debido a mi experiencia con C#- quise hacerlo de la siguiente forma:
Module module=null;
if(e.getPath()==”Aplicaciones/Estadistica/Captura”){
        module=new Captura();
}
if(module!=null){
        openModule(module);
}
donde, e.getPath() me dice el módulo seleccionado. Pues nunca se abría el módulo, incluso depuré el código línea por línea y al inspeccionar las variables veía que tenían el mismo valor. Y efectivamente ese es el detalle, el operador “==” no compara el valor sino la referencia (apuntador), y como en este caso son dos instancias diferentes de cadenas pues nunca entraba en la condición. La solución es simple, hay que utilizar el método “equals()” de la siguiente forma:
if(e.getPath().equals(“Aplicaciones/Estadistica/Captura”)){
        module=new Captura();
}

Referencias:
http://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java

BIRT Viewer – Parameter Display Text is Null

En el título de un reporte necesitaba poner el valor de un párametro, el detalle es que el párametro está enlazado a un DataSet, por lo tanto tiene un value y un displayText. En mi caso es un listado de oficinas, cada una tiene su clave y su nombre, p. ej. BIBL – BIBLIOTECA
Si pongo un DynamicText en el encabezado con el valor
params[“OFICINA”].displayText //despliega BIBLIOTECA
pero únicamente cuando genero el reporte desde Eclipse o en el Report Viewer con la operación “frameset”.
En mi aplicación tengo un botón para imprimir el reporte, que únicamente abre el enlace

http://jboss.midominio.com:8080/ReportViewer/run?__format=pdf&__report=rptInformeMensual.rptdesign&OFICINA=BIBL

para generar el reporte en un documento PDF.
El problema es que en el título, en vez de mostrar “BIBLIOTECA” me aparece el texto “NULL”.
Cómo de todos modos tengo el título de la oficina seleccionada en mi aplicación, decidí enviarla como un parámetro extra y así no tuve ningún problema.
La URL finalmente quedó así
http://jboss.midominio.com:8080/ReportViewer/run?__format=pdf&__report=rptInformeMensual.rptdesign&OFICINA=BIBL&TITULO=BIBLIOTECA
y mi DynamicText del encabezado
params[“TITULO”];

Si tu parámetro es de selección multiple (multi-select) tal vez te interesa ver esto.

GWT – Enviar HTML dentro de JSON mediante RequestBuilder

Hace poco integré el CKEditor en un proyecto. A la hora de enviar el código HTML al servidor tuve algunos problemas con los caracteres especiales.
Y es que hay que asegurarnos de que nuestro JSON sea compatible con su definición; afortunadamente el metodo toString de la clase JSONObject se encarga de “escapar” los caracteres no permitidos en JSON (” \ / \b \f \n \r \t \uXXXX) y nos regresa una cadena válida.

String jsonAcuerdo=new JSONObject(acuerdo).toString();

Finalmente, tenemos que enviar los datos dentro de una variable codificada a HTML de la siguiente forma

RequestBuilder rb = new RequestBuilder(RequestBuilder.POST, URL.encode(jsonUrl));
rb.setHeader("Content-type", "application/x-www-form-urlencoded");
StringBuffer postData = new StringBuffer();
postData.append("acuerdo=").append(URL.encodeComponent(jsonAcuerdo));
rb.sendRequest(postData.toString(),new RequestCallback(){
//TODO on response received
});

aquí es importante utilizar el método “encodeComponent” de la clase URL ya que esté si codifica los caracteres delimitadores de componentes en una URL (; / ? : & = + $ , #) a diferencia del método “encode” que no lo hace. Estos caracteres seguramente estarán presentes en el código HTML que deseemos enviar, por ejemplo en " y ni hablar de los otros. Esta variable será decodificada “automaticamente” cuando la leamos en el servidor mediante el método getParameter de la interfaz ServletRequest

Java – Switch sobre una cadena

En Java no hay forma de hacer un switch sobre una cadena, sin embargo, esta funcionalidad es comun en otros lenguajes.  En java, podemos emular esto de las siguientes maneras con el uso de una enumeración:

public enum Day
{
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
    THURSDAY, FRIDAY, SATURDAY;
}

Dada la enumeracion anterior, podemos hacer el switch de la siguiente forma:

switch (Day.valueOf(str))
{
    case SATURDAY:             
    case SUNDAY:
        // weekend processing …
        break;
    default:
        // weekday processing …
}

El problema con el código anterior es que el método Enum.valueof() lanza una excepción de tipo IllegalArgumentException si la cadena que pasamos como parámetro no corresponde a un valor de la enumeración o NullPointerException si le pasamos un null. Podemos crear un método que atrape estas excepciones y regrese un valor por default.

public enum Day
{
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
    THURSDAY, FRIDAY, SATURDAY,
    NOVALUE;

    public static Day toDay(String str)
    {
        try {
            return valueOf(str);
        }
        catch (IllegalArgumentException ex) {
            return NOVALUE;
        }
    }  
}

Entonces el switch quedaría de la siguiente forma:

switch (Day.toDay(str))
{
    case SUNDAY:               
    case MONDAY:
    case TUESDAY:
        // etc …
    default:
        // any non-Day value
}

Otra manera de implementar la enumeración, pero sin utilizar Excepciones, sería la siguiente:

public enum Day
{
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
    THURSDAY, FRIDAY, SATURDAY,
    NOVALUE;

    public static Day toDay(String str)
    {
        for(Day day:EnumSet.allOf(Day.class)){
       
        if(day.toString().equals(str)){
       
       
        return day;
       
        }
        }
        return Day.NOVALUE;
    }  
}

Fuentes:
Xefer
stackoverflow

Linux – Obtener un hash MD5 desde la linea de comandos

En sistemas UNIX y GNU/Linux se utiliza el algoritmo MD5
para calcular el hash de las claves de los usuarios. En el disco
se guarda el resultado del MD5 de la clave que se introduce al dar de
alta un usuario, y cuando éste quiere entrar en el sistema se compara el
hash MD5 de la clave introducida con el hash que hay
guardado en el disco duro. Si coinciden, es la misma clave y el usuario
será autenticado.

Wikipedia

Hay ocasiones que olvidamos la contraseña, o simplemente queremos insertar un usuario directo en la tabla donde almacenamos el “hash”. Bueno, pues para generar este hash lo podemos hacer desde la linea de comandos de la siguiente forma:

echo -n “secret_password” | md5sum –

El guión al final es opcional

es importante el parámetro -n en el comando echo para que no agregué un carácter de salto de línea

GWT – Darle formato a una fecha


En Java, cuando quiero darle formato a una fecha o “parsear” una cadena para convertirla en un objeto Date, utilizo la clase SimpleDateFormat de la siguiente forma

SimpleDateFormat fmtDate=new SimpleDateFormat(“dd/MM/yyyy”);
String fecha=fmtDate.format(new Date());

Esto lo podemos hacer sin problemas en el servidor 😉 pero, que pasa cuando lo intentamos en el Cliente. Bueno, pues tenemos que utilizar la clase DateTimeFormat de la siguiente manera

DateTimeFormat fmtDate=DateTimeFormat.getFormat(“dd/MM/yyyy”);
String fecha=fmtDate.format(new Date());