domingo, 22 de noviembre de 2009

Encriptar una cadena en Java

En prácticamente todas las aplicaciones, siempre es necesaria la encriptación de algún tipo de información. El ejemplo más simple son las contraseñas de usuario, información personal o cualquier tipo de información sensible dentro del ámbito de la aplicación.

Veamos cómo podemos codificar una cadena cualquiera utilizando el API estandar de Java.

        String claveEncriptada = null;
        String claveOriginal = "No se a quien odio más, a Batman o a Guti";
        String semilla = "0123456789";

        // Generamos una clave secreta.
        SecretKeySpec desKey = new SecretKeySpec(new String((semilla.trim().concat("99999999")).substring(0, 8)).getBytes(), "DES");
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, desKey);
        byte[] claveEncriptadaBytes = cipher.doFinal( claveOriginal.getBytes() );
        claveEncriptada = new BASE64Encoder().encode( claveEncriptadaBytes );






Evidentemente el código mostrado anteriormente habrá que incluirlo en un método con su generador de clave y su bloque try-catch.

Como podemos ver, la cadena que tratamos de codificar es: "No se a quien odio más, a Batman o a Guti" y el resultado que obtendríamos si ejecutaramos las instrucciones del listado sería: "WZMLNsMJeI2PDCPuWudVucLfRyQlffqA1yYKWLOLuCv2SzIcw0Aegh6w3o6FjQ3T".

La semilla, es utilizada por el algoritmo de encriptación para cifrar la cadena. Si quisieramos desencriptar la cadena obtenida, necesitaríamos la semilla para poder hacerlo. Es como la llave que abre la caja fuerte que contiene el contenido desencriptado original. A la hora de realizar una aplicación es de suma importancia que cada dato que encriptemos tenga una semilla diferente para no comprometer el total de la información en el caso de que la misma sea descubierta. El mecanismo para la elección debe ser elegido cuidadosamente para dificultar el trabajo a un posible "ladrón" que quisiera acceder a la información.

Es importante tener en cuenta que la encriptación genera una cadena de bytes, los cuales, transformados en una cadena de carácteres podría implicar la existencia de carácteres extraños en la misma, cosa que nos podría dar problemas a la hora de almacenar la información encriptada en una base de datos si no tenemos en cuenta que podemos insertar dicho tipo de cadenas a la hora de almacenarlas en fichero o base de datos. Para evitar dicho problema, utilizamos el codificación BASE64.

Ver artículo: Desencriptar una cadena en Java

Gracias a Gomstor por encontrar un error en el código que ya ha sido corregido.

sábado, 14 de noviembre de 2009

DNI, NIF, NIE

Muchas veces, a la hora de escribir un programa, hacer una web, etc, nos vemos en la necesidad de recoger información personal de un usuario, y en algunos casos, entre dicha información nos encontramos con el NIF/NIE de alguna persona.

Siempre que me he puesto a buscar por internet adelante, he encontrado montones de scripts que validan, calculan y formatean los NIFs, pero nunca he encontrado uno que me sirviera para los números de identificación de extranjeros, NIE.

¿Qué es eso del NIE? Pues muy sencillo, es un NIF para extranjeros. En un principio puede parecer una chorrada, pero no lo es en absoluto. Por ejemplo: Un inglés, llamémosle Paul Gascoigne, por ejemplo, quiere comprarse un pisito en Benidorm para pasar sus vacaciones en alguna terraza de la ciudad nadando en cerveza. Para realizar la compra necesitará un número de identificación ante hacienda (que somos todos, incuidos algunos extranjeros). Un NIF no se le puede dar, pues es sólo para personas con nacionalidad española. Por eso David, deberá obtener un NIE antes de poder adquirir su pisito-resaquero.

Básicamente un NIE es lo mismo que un NIF pero en el que se ha cambiado su primer dígito por una letra, que puede ser X, Y o Z. Por otro lado, a la hora de calcular la letra final, estas X,Y o Z se substituyen por un 0, 1 o 2 respectivamente, a partir de este momento, el cálculo es exáctamente el mismo que para el NIF.

A continuación muesto una serie de funciones javascript para validar y calcular automáticamente tanto NIF como NIE:

/*
  * Por CNG (www.trapallada.com).
  */
  function esNumerico(x)
  {
    var expresionRegularNDigitos = /^(\d*)$/;
    return x.match(expresionRegularNDigitos);
  }

  function esNifNie(x)
  {
    var expresionRegularNIE = /^[X-Z0-9]{1}[0-9]{7}$/;
    return x.match(expresionRegularNIE);
  }

  function obtenLetraNIF ( dni, destino )
  {
    dni.value = dni.value.toUpperCase();
    if ( esNifNie( dni.value ) )
    {
      var nifTmp = '';
      if ( esNumerico( dni.value ) )
      {
        nifTmp = dni.value;
      }
      else
      {
        switch( dni.value.charAt(0).toUpperCase() )
        {
          case 'X': nifTmp = dni.value.replace(/X/gi, "0");
                    break;
          case 'Y': nifTmp = dni.value.replace(/Y/gi, "1");
                    break;
          case 'Z': nifTmp = dni.value.replace(/Z/gi, "2");
                    break;
          default:  alert('NIF/NIE incorrecto');
        }
      }

        if ( nifTmp.length == 8 )
        {
          var cadena = 'TRWAGMYFPDXBNJZSQVHLCKET';
          var posicion = nifTmp % 23;
          destino.value = cadena.charAt(posicion);
        }
        else
        {
          destino.value = '';
        }
      }
      else
      {
        alert('NIF/NIE incorrecto');
      }
    }  
  }


Para probar este código deberemos incluir un inputbox html que realice las llamadas adecuadas:







CC-GNU LGPL


Este software está sujeto a la CC-GNU LGPL o superior.

domingo, 8 de noviembre de 2009

Convertir código ASP a PHP.

Problema: Dispongo de una web que hice hace tiempo utilizando tecnología ASP con conexiones a una base de datos access y ahora:

1- Quiero cambiar de tipo de servidor en mi proveedor de hospedaje a uno en linux para pagar menos al mes.

2- Quiero dejar de utilizar mi web para utilizar alguna herramienta de publicación como Wordpress o un CMS.

En ambos casos me gustaría poder seguir utilizando algunas de mis funciones ASP sin tener que recodificar todo manualmente, ya que eso me haría perder bastante tiempo.

Solución: ¡¡¡asp2php!!!

Se trata de un programita que te permite convertir código asp a php, respetando bastante la estructura original de los fichero, por lo que te será fácil retocar el código php generado si no tienes demasiados conocimientos de php, aunque sea símplemente por comparación con el archivo ASP original.

Pero veamos un ejemplo con los resultados de la conversión:

' Por CNG (www.trapallada.com).
Function getLiteral(intIdLiteral)
Set DB = Server.CreateObject("ADODB.Connection")
Set RS = Server.CreateObject("ADODB.Recordset")
DB.Mode = adModeReadWrite
DB.Open "dsn=miDSN;"

strSQL = "select literal from tLiterales where id=" + CStr(intIdLiteral)
RS.Open strSQL, DB, 3, 2
If RS.EOF or RS.BOF Then
strLiteral= "null"
Else
strLiteral= Trim(RS.Fields(0).Value)
End If
RS.Close
DB.Close
getLiteral= strENUNCIADO
End Function

generaría

// Por CNG (www.trapallada.com).
function getLiteral($intIdLiteral)
{
extract($GLOBALS);

// $DB is of type "ADODB.Connection"
// $RS is of type "ADODB.Recordset"
echo $adModeReadWrite;
$DB=mysql_connect("servidorDDSS","","");
mysql_select_db("",$DB);

$strSQL="select literal from tLiterales where id="+($intIdLiteral);
$rs=mysql_query($strSQL);
if (($RS==0) || ($RS_BOF==1))
{
$strLiteral="null";
}
else
{
$strLiteral=trim((0)->$Value);
}
mysql_close($DB);
$function_ret=$strLiteral;
return $function_ret;
}


El programa funciona en línea de comandos, pero para evitar lo engorroso del mismo, existen diferentes frontales para windows, MacOX e incluso para entorno web.  Yo sólo he probado el asp2php shell, con resultados magníficos por cierto. Lo único que hay que hacer es descomprimir el los archivos de asp2php y de asp2php shell en la misma carpeta.