martes, 19 de julio de 2011

Cómo recuperar sectores dañandos del disco duro dese la linea de comados de linux


Los discos duros no son eternos y a menos de que sean de estado sólido, están sujetos a errores de escritura por una mala imantación o por otras causas que son ajenas a uno como usuario. Así que siempre es bueno hacer un backup de nuestros datos en una unidad externa, ya sea en un storage en la red o en una usb que este bien oculta bajo la almohada.

Una buena práctica es hacerlo cuando el sistema operativo empiece a decirnos este tipo de cosas, que si no lo hacemos, a la larga nos sea más difícil o tardado este tipo de cosas. Así que hagan caso, hagan un back up y denle a esos sectores.

¿Cómo lo hacemos?

Abrimos nuestra tan amada consola para los que somos "consoleros" de corazón, para los que no, igual, abran la consola y cambien a super usuario.

Lo más recomendable es que si como yo, tienen más de una partición o de plano no se acuerdan del nombre de la partición, ejecuten fdisk

[root@uetiko]# fdisk -l
Disposit. Inicio Comienzo Fin Bloques Id Sistema
/dev/sda1 * 1 10947 87931746 5 Extendida
/dev/sda2 10948 19092 65424712+ 83 Linux
/dev/sda3 19093 19457 2931862+ 82 Linux swap / Solaris
/dev/sda5 1 10947 87931714+ 83 Linux

Y es así como ya teniendo nuestro listado de particiones, podremos reparar los sectores. Es importante que la partición ese desmontada o nos dará dolores de cabeza cuando nos salga que el dispositivo está siendo ocupado.

Para esto, basta un unmount podremos resolver el problema

[root@uetiko]# unmount /deb/sda1

Y ahora si, viene el momento de la verdad, y es aquí donde radica la magia para poder un disco duro guapo y en forma. Para ello usamos un comando que se llama badblocks, el cual tiene muchas chunchitas para que podamos analizar y reparar sectores y demás, pero por ahora nos limitaremos a jalar del gatillo y esperar que el disparo de en el blanco. Si no lo tienen, solo bájenlo de los repositorios con su gestos de paquetes preferido según su diestro.

[root@uetiko]# badblocks -s -v -f /dev/sda1

Y esperen a que el programa haga su trabajo. Claro, esto les causara un infarto cuando termine y vean que algunos de sus datos han... como decirlo, desaparecido extrañamente, para evitar esto y que en lo personal, no recomiendo, es agregar la opción -n para que así, no borre ningún dato cuando repare los sectores dañados, claro, esto les llevara mucho, pero mucho tiempo, así que si lo hacen, recomiendo que salgan al cine con la novia/amiga, la lleven a cenar y después regresen haciendo paradas en cualquier bar/cafetería que encuentren.

sábado, 24 de abril de 2010

Validar una clave Privada con su Certificado en JAVA

Hola de nuevo, como que esto de escribir en el blog ya me me esta gustando, bueno, solo como complemento de la entrada anterior donde encriptamos un archivo con la llave privada queria escribor como validar un archivo con un certificado.

Para esto lo que se tiene que hacer es crear un objeto X509Certificat a partir un byte[] o un InputStream que contiene el archivo.cer

File archivoCer = new File("c:/certificado.cer");
InputStream fis = new FileInputStream(archivoCer);// Se maneja la excepcion
X509Certificate cert = X509Certificate.getInstance(fis);

A continuacion se crea un objeto Signature pasandole e algoritmo de encripcion, en nuestro caso es el MD5withRSA, este es el mismo objeto que utilizamos para firmar nuestro archivo, pero esta vez lo inicializaremos para verificar nuestro archivo firmado con el certificado que tenemos

Signature firma = Signature.getInstance("MD5withRSA");
firma.initVerify(cert.getPublicKey());

A continuacion le cargamos el archivo o texto sin firmar

firma.update(textoAFirmar.getBytes("UTF-8"));

Y por ultimo verificamos el archivo firmado, donde textoFirmado en un byte[] que obtuvimos despues de firmar un archivo

firma.verify(textoFirmado)

Bueno, espero que les halla servido, yo tuve que utilizar esto para verificar que el certifiado fuera valido con respecto al la clave privada que estaba ingresando, bueno les pego el codigo de toda la clase para que lo entiendan mejor:

package com.infosoft.rasengan.util;

import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.SignatureException;

import javax.security.cert.CertificateException;
import javax.security.cert.X509Certificate;

import org.apache.commons.ssl.PKCS8Key;
import org.apache.commons.ssl.ProbablyNotPKCS8Exception;

public class CertificateValidator {

public final static int SUCCESS = 0;
public final static int ERROR_PASSWORD = 1;
public final static int ERROR_PRIVATE_KEY = 2;
public final static int ERROR_PUBLIC_KEY = 3;
public final static int ERROR_PUBLIC_PRIVATE_KEY = 4;

private byte[] clavePrivada;
private byte[] clavePublica;
private String password;

public CertificateValidator(InputStream archivoClavePrivada,
InputStream archivoClavePublica, String password) {
this.clavePrivada = FormatUtil.getBytes(archivoClavePrivada);
this.clavePublica = FormatUtil.getBytes(archivoClavePublica);
this.password = password;
}

/**
* Valida el certificado digital, la clave privada, asi como su relacion
*
* @return - 0 si todo esta correcto
* - 1 si el password de la clave privada no es correcto
* - 2 si la clave privada no es un archivo que corresponda al estandar PKCS8
* - 3 si el certificado no es un archivo que corresponda al estandar PKCS10
* - 4 si el certificado no corresponde a la clave privada
*/

public int validate() {
String textoAFirmar = "||2.0|FDF|28125|2007-09-12T12:47:31|11160|2007|ingreso|Pago en una sola exhibicion|"
+ "TERMINOS CONTADO ESP|3674.13|4225.25|IMM9304016Z4|Ingram Micro Mexico S.A. de C.V.|Laguna de Terminos|249|"
+ "Anahuac|Miguel Hidalgo|Distrito Federal|Mexico|11320|Av. 16 de Septiembre|225|San MartinXochinahuac|"
+ "Azcapotzalco|Distrito Federal|Mexico|02140|CAOG8406274R0|CHAVEZ OCHOA GABRIEL|HDA. DE CORLOME NO. 51|"
+ "COL. FLORESTA COYOACAN|DELG. TLALPAN|MEXICO, D.F. MX 14310|MX|3.00|"
+ "TONER NEGRO P/LASERJET SUPL 2420 (6,000 PAG )|1189.04|3567.12|1.00|COMISION TARJETA DECREDITO|"
+ "107.01|107.01|IVA|15.00|551.12|551.12||";
try {
PKCS8Key pkcs8 = new PKCS8Key(clavePrivada, password.toCharArray());
PrivateKey pk = pkcs8.getPrivateKey();
Signature firma = Signature.getInstance("MD5withRSA");
firma.initSign(pk);
firma.update(textoAFirmar.getBytes("UTF-8"));
byte[] firmado = firma.sign();
X509Certificate cert = X509Certificate.getInstance(clavePublica);
cert.checkValidity();
firma.initVerify(cert.getPublicKey());
firma.update(textoAFirmar.getBytes("UTF-8"));
if (firma.verify(firmado)) {
return SUCCESS;
} else {
return ERROR_PUBLIC_PRIVATE_KEY;
}
} catch (ProbablyNotPKCS8Exception e) {
return ERROR_PRIVATE_KEY;
} catch (UnsupportedEncodingException e) {
return ERROR_PRIVATE_KEY;
} catch (SignatureException e) {
return ERROR_PRIVATE_KEY;
} catch (GeneralSecurityException e) {
return ERROR_PASSWORD;
} catch (CertificateException e) {
return ERROR_PUBLIC_KEY;
}
}

}

Saludos

jueves, 18 de febrero de 2010

Como obtener el sello digital con JAVA

Hola el objetivo de esta entrada es explicar cómo crear un sello digital, para la facturación electrónica.

Escribo esto porque tuve muchos problemas para poder crearlo, mi primer problema fue el poder leer la llave privada que te da el SAT, ya que esta viene ecriptada con un password y encontré poca información de como leerla en java.

Bueno, basta de quejas, empecemos!

Lo primero que hay que hacer es generar la cadena original, la creación de esta cadena esta especificada en el anexo 20 de la Resolución Miscelánea Fiscal inciso D. Esta es una cadena formada con los datos de la factura, estos datos están separados por el carácter pipe ”|”, y se inicia y finaliza esta cadena con un doble pipe “||”.
Aquí le s dejo un ejemplo de la cadena Original.

||2.0|AB|32|2010-02-18T12:30:03|434|2006|ingreso|EFECTIVO|3000.00|45029.85|02934INFOSOFT|Infosoft & Xgress|arenas|98|Coyoacan|DF|México|54832|4503495WXGF4|México|2|Impresoras|1500.00|3000.00|2|PC|2000.00|4000.00|IVA|15.00|2900.85|2900.85||

Ya que tenemos la cadena original lo siguiente es pasarla por un algoritmo de digestión como es el MD5, y el resultado pasarlo por un algoritmo de encriptación RSA, estos dos pasos se pueden hacer en uno solo con el api de java. Para esto lo primero que necesitamos es la clave privada (archivo.key) que nos proporcionó el SAT junto con su password. Esta clave esta codificada según el estándar PKCS8 en formato DER. Además esta clave esta encriptada con un password.
Para poder des enriptarla utilizaremos la librería commons-ssl de apache. De esa libraría utilizaremos el objeto PKCS8Key de la siguiente manera:

PKCS8Key pkcs8 = new PKCS8Key(clavePrivada, password.toCharArray());

Donde clavePrivada es un arreglo de bytes que contiene la clave privada.
Para poder obtener la clave privada solo se la pedimos a este objeto:

java.security.PrivateKey pk = pkcs8.getPrivateKey();

Lo siguiente que hay que hacer es obtener el objeto que codificara en MD5 y RSA nuestra cadena, e inicializarlo con la clave privada este es java.security.Signature.

Signature firma = Signature.getInstance("MD5withRSA");
firma.initSign(pk);

donde pk es la clave privada que obtuvimos.
Al objeto Signature se le pasa la cadena original convertida en bytes con formato UFT-8
firma.update(cadenaOriginal.getBytes("UTF-8"));
y obtenemos el arreglo de bytes con la cadena original encriptada.

byte[] cadenaFirmada = firma.sign();

A continuación se codifica en base 64 la cadena para poder obtener caracteres imprimibles con el objeto sun.misc.BASE64Encoder.

BASE64Encoder b64 = new BASE64Encoder();
String selloDigital = b64.encode(firma.sign());

Y con esto obtenemos una cadena como esta que es el sello digital

UdjknEGo/r0v7QrAhvL+aFKkl6Jk6b4pNvRYI0ymWrW19k4DjzygbtTnAnB0HNmafifTNzxB+/wE
JsJKGWjbnSAO61gy6JTLSvrdS+KPKpQtxYH8/7Ib55J8T4PuIL0a6qmAwpMFrHToSaAO0NXG3W9t
homWp8b+UdbJ2qL/ABI=

Les dejo el código completo para que lo revisen.


package com.infosoft.rasengan.cfd;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
import java.security.Signature;

import org.apache.commons.ssl.PKCS8Key;
import org.jdom.Document;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.jdom.output.Format.TextMode;

import sun.misc.BASE64Encoder;

import com.infosoft.rasengan.cfd.bean.Comprobante;
/**
* Clase que genera el comprobante fiscal digital asi como el sello digital
* @author Xgress
*
*/
public class GeneradorCFD {

private Comprobante comprobante;

/**
* Constructor que inicializa el objeto con un Comprobante, genera el
* selloDigital y se lo agrega al objeto Comprobante
*
* @param comprobante
* Objeto que contiene todos los datos de un Comprobante Fiscal
* Digital
* @param archivoClavePrivada
* InputStream que contiene el archivo .key de la llave privada
* @param password
* String con el password de la llave privada
* @throws GeneralSecurityException
* Excepcion arrogada cuando el password no es el correcto
*/
public GeneradorCFD(Comprobante comprobante,
InputStream archivoClavePrivada, String password)
throws GeneralSecurityException {
this.comprobante = comprobante;
this.comprobante
.setSello(getSelloDigital(archivoClavePrivada, password));
}

/**
* Metodo que genera el sello digital a partir de la cadena original y la
* clave privada siguiendo los siguientes pasos: 1)Se le aplica la funcion
* hash de digestion MD5 a la cadena original y se aplica el algoritmo de
* encripcion RSA con la clave privada. 2) Se codifica el resultado a Base64
* teniendo como resultado una cadena imprimible.
*
* @param archivoClavePrivada
* InputStream que contiene la clave privada(archivo .key)
* @param password
* String con el password de la clave privada
* @return String con el sello digital
* @throws GeneralSecurityException
* Excepcion arrogada cuando el password no es el correcto
*/
public String getSelloDigital(InputStream archivoClavePrivada,
String password) throws GeneralSecurityException {
String cadenaOriginal = comprobante.getCadenaOriginal();
System.out.println(cadenaOriginal);
byte[] clavePrivada = getBytes(archivoClavePrivada);
PKCS8Key pkcs8 = new PKCS8Key(clavePrivada, password.toCharArray());
PrivateKey pk = pkcs8.getPrivateKey();
Signature firma = Signature.getInstance("MD5withRSA");
firma.initSign(pk);
String selloDigital = null;
try {
firma.update(cadenaOriginal.getBytes("UTF-8"));
BASE64Encoder b64 = new BASE64Encoder();
selloDigital = b64.encode(firma.sign());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
System.out.println(selloDigital);
return selloDigital;
}

/**
* Genera el xml extensible del comprobante fiscal digital
* @return String con el xml
*/
public String getCFD() {
Format format = Format.getPrettyFormat();
format.setEncoding("utf-8");
format.setTextMode(TextMode.NORMALIZE);
XMLOutputter xmlOutputer = new XMLOutputter(format);
String res = xmlOutputer
.outputString(new Document(comprobante.getXML()));
try {
res = new String(res.getBytes("UTF-8"));//TODO: probar bien
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return res;
}
/**
* Metodo que convierte un input stream con la llave privada a un array de bytes
* @param is InputSteam con la clave privada
* @return Arreglo de bytes con la clave privada
*/
private byte[] getBytes(InputStream is) {
int totalBytes = 714;
byte[] buffer = null;
try {
buffer = new byte[totalBytes];
is.read(buffer, 0, totalBytes);
is.close();
} catch (IOException e) {
e.printStackTrace();
}
return buffer;
}

}

jueves, 27 de agosto de 2009

martes, 7 de julio de 2009

Google se quita el tag "Beta"

Hoy se ha lanzado un anuncio desde el blog oficial de Google que nos dice que después de tan solo tres miseros años, Google ha decidido qutarle la etiqueta "BETA" a su paquete Google Apps, Gmail (Tan solo cinco años de ser beta, creí que moriría sin pasar a algo estable.), Docs, Calendar y Talk han dejado de ser aplicaciones feas e inestables. Pero si se preguntan que va a pasar, pues la respuesta es si, siguen siendo gratuitos para que no se pongan a gritar antes de tiempo.

Así que la proxima vez que Gmail te deje sin tus correos, podrás lanzar un par de recordatorios familiares. Al fin y al cabo, ya no servira la excusa "Esta en fase beta, suele pasar..." O eso dice la teoria.

lunes, 1 de junio de 2009

COBOL llega su mitad de siglo.



Hace 50 años nació gracias a la comisión CODASYL y el Departamento de Defensa de los Estados Unidos, Su nombre: COBOL (COmmon Business-Oriented Language)

La idea nació de Grace Murray Hopper, un científico y militar norteamericana, que buscaba crear un lenguaje de programación fácil de comprender. Y por ello se le considera como la madre de COBOL.

El primer boceto de Cobol fue presentado formalmente en el año de 1960 y su actual estandarización fue dada hasta el 2002. Con esto nace el divorcio entre software y Hardware.

Y pensar que a 50 años de su nacimiento se sigue usando principalmente en la banca para los cajeros automaticos o pago con tarjetas de credito. La realidad es que para los corporativos les resulta caro y laborioso migrar sus sistemas a otra plataforma y aun mas dificil se vuelve encontrar programadores en COBOL, ya me imagino a estos corporativos de visita a los museos en busca de algún fósil de programador para tratar de clonarlo.

Aunque Cobol es considerado a menudo un lenguaje mainframe algo anticuado, lo cierto es que en lo absoluto es obsoleto.

domingo, 24 de mayo de 2009

Leonidas se retrasa una semana

Que les puedo decir. Jesse Keating de la Red Hat ha dicho 'No hay leonidas' para este 26 de mayo. Por lo que ha anunciado que se retraza una semana (7 días) para darle a los 24 bugs detectados en las versiones de prueba. Pero mientras esto pasa y nos tienen como novia de pueblo hasta el 2 de junio, podemos matar el tiempo en la discución de cual será el nombre de la próxima versión del diestro (el numero 12), ¿alguien dijo yo?