Come modificare un certificato usando il metodo getTBSCertificate ()

0

Voglio mostrare che se modifico un bit o un byte da un determinato certificato X509 i risultati della verifica della firma sono falsi (poiché questa modifica risulta dal valore hash diverso dal certificato). Sono bloccato nel caso in cui come fare la modifica sul certificato utilizzando il metodo getTBSCertificate (). Il mio codice seguente fa il processo di verifica perfettamente, ma ho provato a farlo fallire usando l'idea di modifica di bit o byte ma non funziona. Si noti che questa idea che ho proposto è quella di dimostrare che qualsiasi modifica sul certificato causerà un errore durante la verifica della 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;
        }
}
    
posta Mike 20.02.2014 - 04:49
fonte

1 risposta

2

Mr. Mike, tutto quello che devi fare è ottenere i dati delle righe dati certificati con codifica DER (parte TBS) e puoi estrarli come di seguito

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(); 

Quindi copia il contenuto dell'array tb in un altro array bcopy attraverso un loop e fai tutte le modifiche che vuoi (cioè usando la tecnica di mascheramento Anding con x55) dopo di che puoi ottenere il valore hash tramite

 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;
}

a questo punto hai il valore hash del certificato modificato, puoi andare ora ed estrarre la firma dal certificato originale [ byte[] sig= x509cert.getSignature(); ] e decodificare la firma per ottenere il valore hash e confrontarlo con il valore hash modificato , buona fortuna;)

    
risposta data 23.02.2014 - 03:31
fonte

Leggi altre domande sui tag