0

I tried to sniff the network data flow and extract the certificates for HTTPS with Java. (In python, the package named Scapy could achieve this.) My ultimate goal is to dump the packets and find the domain name containing in their certificates (if any).

I have explored a bit but most articles focus on either dumping the packet & printing out simple information (eg. addr, port), or reading the certificate from file and somehow parsing it. I don't find any to combine these two.

I have tried Jpcap and to parse the packets (it's not my code, I modified this code from Internet). But I failed to extract the correct certificate from it.

Here is the main code:

// implements PacketReceiver
@Override
public void receivePacket(Packet p)
{
    if (p instanceof TCPPacket)
    {
        TCPPacket tcp = (TCPPacket) p;
        // receivePost == 443
        if (tcp.src_port == receivePost || tcp.dst_port == receivePost)
        {
            byte[] bytes = tcp.data;
            // ((int) bytes[0]) == 22 -> Handshake
            // This is the main part I'm not sure. Some packets do go into this if.
            if (bytes != null && bytes.length > 6 && ((int) bytes[0]) == 22)
            {
                StringBuffer buf = new StringBuffer();

                for (int i = 0, j; i < bytes.length;)
                {
                    for (j = 0; j < 8 && i < bytes.length; j++, i++)
                    {
                        String d = Integer
                                .toHexString((int) (bytes[i] & 0xff));
                        buf.append((d.length() == 1 ? "0" + d : d) + " ");
                        if (bytes[i] < 32 || bytes[i] > 126)
                            bytes[i] = 46;
                    }
                }

                String[] data = buf.toString().split(" ");
                // Parse the length of cert
                // I must be wrong here, the length is extremely large
                int certLength = Integer.parseInt(data[12] + data[13]
                        + data[14], 16);
                // Extract the cert
                StringBuffer certString = new StringBuffer();
                for (int i = 0; i < certLength; i++)
                {
                    certString.append(data[i + 15]);
                }
                // The byte array to store the cert
                byte[] cert = new byte[certLength];

                for (int i = 0; i < certLength; i++)
                {
                    String tempstr = certString.substring(i * 2, i * 2 + 2);
                    cert[i] = uniteBytes(tempstr);
                }

                try
                {
                    CertificateFactory certFactory = CertificateFactory
                            .getInstance("X.509");
                    InputStream in = new ByteArrayInputStream(bytes);
                    X509Certificate xcert = (X509Certificate) certFactory
                            .generateCertificate(in);
                    System.out.println("DN:"
                            + xcert.getSubjectDN().getName());
                } catch (CertificateException e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

Please help me. Thanks in advance!

zzy
  • 751
  • 1
  • 13
  • 25
  • 1
    Why do all that when the OpenSSL [`s_client`](https://www.openssl.org/docs/manmaster/apps/s_client.html) command will give you the certificate, free and clear? – Andreas Aug 07 '16 at 17:58
  • @Andreas Because I want to get the cert from ongoing connections. And I may not know which connections exist. Do you have any idea whether this OpenSSL tool could achieve this? Thanks! – zzy Aug 07 '16 at 18:35

0 Answers0