Cómo modificar un certificado usando el método getTBSCertificate ()

0

Quiero mostrar que si modifico un bit o byte de un certificado X509 dado, la verificación de la firma da como resultado falso (porque esta modificación produce un valor hash diferente del certificado). Estoy atascado en el caso de cómo hacer la modificación en el certificado utilizando el método getTBSCertificate (). Mi siguiente código hace el proceso de verificación perfectamente, PERO traté de hacerlo fallar usando la idea de modificación de bit o byte, pero no funciona. Tenga en cuenta que esta idea que propuse es probar que cualquier modificación en el certificado fallará mientras se verifica la firma

 public class VerifyX509 {

private static Certificate getCACert;
private static Certificate[] getCert;

public static void main(String[] args) throws CertificateEncodingException {
    setURLConnection("https://www.google.com");
    X509Certificate x509cert= (X509Certificate) getCert[0];
    byte[] b= x509cert.getTBSCertificate();
    b[0] = (byte) ~b[0];
    // HOW TO UPDATE getTBSCertificate() after flipping the b[0] to make Verify() in my method verifySign() return false!
    verifySign();

  }


public static void setURLConnection(String link){

    try{
        int i=1;
        URL destinationURL = new URL(link);
        HttpsURLConnection con = (HttpsURLConnection) destinationURL.openConnection();
        con.connect();
        getCert = con.getServerCertificates();
        for (Certificate c : getCert) 
        {
            if (i==2)
            {
                getCACert= c;
                return;
            }
            i+=1;
        }
        }catch (Exception e1) {
        JOptionPane.showMessageDialog(null, "Error while connection! Check your Internet Connection.");
        e1.printStackTrace();
        }

}


public static boolean verifySign()
{

        try
        {
            getCert[0].verify(getCACert.getPublicKey());
            return true;
        } catch (GeneralSecurityException e2)
        {
            return false;
        }
}
    
pregunta Mike 20.02.2014 - 04:49
fuente

1 respuesta

2

Sr. Mike, todo lo que tienes que hacer es obtener la información del certificado codificado en DER de datos de la fila (parte TBS) y puedes extraerla como se muestra a continuación

URL url = new URL("https://www.google.com/");
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.connect();
Certificate userCert[] = con.getServerCertificates();
        X509Certificate x509cert = ((X509Certificate) userCert[0]);


    byte[] tbs=x509cert.getTBSCertificate(); 

Luego, copie el contenido de la tbs de la matriz a otra copia de la matriz a través de un bucle y haga las modificaciones que desee (es decir, utilizando la técnica de enmascaramiento Anding con x55) después de eso, puede obtener el valor hash a través de

 String sha1 = "";
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
        crypt.reset();
        crypt.update(bcopy);
        sha1 = byteToHex(crypt.digest());

private static String byteToHex(final byte[] hash)
{
    Formatter formatter = new Formatter();
    for (byte b : hash)
    {
        formatter.format("%02x", b);
    }
    String result = formatter.toString();
    formatter.close();
    return result;
}

En este punto, tiene el valor hash del certificado modificado, puede ir ahora y extraer la firma del certificado original [ byte[] sig= x509cert.getSignature(); ] y descifrar la firma para obtener el valor hash y compararlo con el valor hash modificado , buena suerte;)

    
respondido por el Ahmed Shatnawi 23.02.2014 - 03:31
fuente

Lea otras preguntas en las etiquetas