Click here to Skip to main content
15,890,123 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I want to show that an X509 certificate doesn't verify with its issuer (I mean verifying the signature would fail in some reason). In this case, it is obvious that flipping, adding, or any other operation on one bit or byte of the certificate itself will make it invalid while verification process( so verify() method will result FALSE which indicates that it's invalid certificate). However, I'm stuck in the case that how to do the modification on the certificate using getTBSCertificate() because it will be loaded in the memory by then. My following code does the verification process perfectly BUT I tried to make it fail using this idea but it doesn't work. Note that this idea I proposed is to proof that any modification on the certificate will fail the signature verification.


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

1 solution

Mr. Mike, all what you have to do is to get the row data DER-encoded certificate information (TBS part) and you can extract it as below

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


Then copy the content of the array b to another array bcopy through a loop and do what ever modifications you want (i.e by using the masking technique Anding with x55) after that you can get the hash value through

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

at this point you have the hash value of the modified certificate, you can go now and extract the signature from the original certificate [ byte[] sig= x509cert.getSignature(); ] and decrypt the signature to get the hash value and compare it with the modified hash value, hope that I helped good luck ;)
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900