Category Archives: Crypto

Using Certificate-Transparency to grab a list of all hostnames a CA has issued certificates for

Certificate Transparency is an approach to improve the security of CAs issuing X.509 certificates by running a public audit-log for all issued certificates. Before a CA issues a certificate, the tbsCertificate structure (which is effectively the whole certificate without the signature) is submitted to a certificate transparency server. Should a CA issue (willingly or due to a compromise) a fraudulent certificate, it is either immediately available in the audit log and can therefore be spotted by an independent third party before it causes damage, or spotting a certificate in the wild that is not included in the audit log is a direct proof that the CA has been compromised.

How to get the hostnames from the log

Since the CT API does not have a single command that returns all the names the CA has issued certificates for, I decided to write a spider by myself in python. The tool is available on github. To download, simply type:

git clone https://github.com/eriktews/certificate-transparency-tools.git
cd certificate-transparency-tools
mkdir out
python download_all_certs.py https://ct1.digicert-ct.com/log out/digicert-
find out/ -name "digicert*precert*" | xargs -n 8000 python get_precert_cn.py | sort -u > all-digicert-pre-certificate-names-sorted.txt

The result should be a sorted list of all hostnames (including with wildcards) digicert every issued a certificate for.

Future work

So far, no special verification of the data supplied by the digicert server is done. Feel free to submit patches on github to improve this code. Also feel free to play with the data and spot any hostnames in the result that looks suspicious to you.

Generating safe prime numbers in Python

Recently, I tried to generate safe prime numbers in a Python program. Python is a nice language when it comes to implementing code that needs to deal with long numbers and arbitrary precision integer arithmetic. Python has build in support for arbitrary precision integers, and operators like +, *, or ** can be overloaded.

If the native support for long numbers in Python seems to be to slow, there is gmpy, a Python C-binding, that allows you to use the GMP library from your python code. Due to the nice operator overloading in Python, you don’t need to change anything in your calculations, except for the initialization of your data.

GMP supports finding prime numbers and also efficient prime testing, bue there is no support for generating safe prime numbers in python and/or in GMP. A number p is a safe prime number, if p is prime, and (p-1)/2 is a prime number too. OpenSSL supports the generation of such numbers. So I decided to write an OpenSSL Python binding, to make it possible to generate these numbers in a Python script, without having to call an external program.

My implementation gensafeprime can be downloaded from github, and is also available on PyPi. Using the code is easy. The following example will generate a 512 bit safe prime number:

#!/usr/bin/python
 
import gensafeprime
print gensafeprime.generate(512)

 

Using SSL/TLS Client Certificate Authentification in Android Applications

Assume that you want to write an Android application, that needs to communicate with your server or your wireless router at home, for personal use. You might be interested in securing this communication against eavesdropping, so that nobody else sees, what you application sends and receives. You also might be interested in authenticating you communication, so that you can be sure that only your application and your server or router communicate, and nobody else is able to modify the content transmitted, without being noticed. The SSL/TLS protocol is a perfect solution for this problem, so that you don’t need to invent a solution yourself.

Certificates

To ensure authenticity of both communication partners, X.509 certificates can be used. Most secure websites in the internet like paypal, ebay, or amazon only use X.509 certificates for the server, and the client is authenticated using a username and a password. For this example, X.509 certificates will be used for both communication partners.

To generate two self-signed X.509 certificates, the following script can be used. It will generate two new RSA 2048 bit keys, generate two self signed certificates, and bundle the client certificate with the corresponding private key, and the servers public certificate in a PKCS#12 container file.

#!/bin/bash
OPENSSL_OPTS="-new -newkey rsa:2048 -nodes -days 5475 -x509"
CN_SERVER="/CN=server"
CN_CLIENT="/CN=client"
PASS="123456"
echo "Generating keys"
openssl req -keyout key-server.pem -subj "$CN_SERVER" \
 -out cert-server.pem $OPENSSL_OPTS
openssl req -keyout key-client.pem -subj "$CN_CLIENT"\
 -out cert-client.pem $OPENSSL_OPTS
echo "Encrypting key for the client now"
openssl pkcs12 -export -passout "pass:$PASS" \
 -in cert-client.pem -inkey key-client.pem -out client.p12 \
 -certfile cert-server.pem -name "Client" -caname "Server"

Stunnel

We will use stunnel for the server. Stunnel is a lightweight general SSL/TLS wrapper and proxy. First, we copy cert-client.pem cert-server.pem and key-server.pem to the server to /etc/ssl/stunnel or another directory. Next is the stunnel configuration file:

cert = /etc/ssl/stunnel/cert-server.pem
key = /etc/ssl/stunnel/key-server.pem
CAfile = /etc/ssl/stunnel/cert-client.pem
sslVersion = SSLv3
chroot = /var/lib/stunnel4/
setuid = stunnel4
setgid = stunnel4
pid = /stunnel4.pid
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
[service]
accept  = 1279
connect = target:1280
verify = 2

This will set up a stunnel server, listening on port 1279, and forwarding the unencrypted communication to target port 1280. It will only allow connections from a client, presenting a valid certificate.

Android

Next, we can write the code for our Android application:

// Adopt this in your application
String PASSWORD_FOR_PKCS12 = "123456";
InputStream pkcs12in = ......
// You only need to execute this code once
SSLContext context = SSLContext.getInstance("TLS");
// Local client certificate and key and server certificate
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(pkcs12in, PASSWORD_FOR_PKCS12.toCharArray());
// Build a TrustManager, that trusts only the server certificate
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
KeyStore keyStoreCA = KeyStore.getInstance("BKS");
keyStoreCA.load(null, null);
Certificate c = keyStore.getCertificate("Server");
keyStoreCA.setCertificateEntry("Server", c);
tmf.init(keyStoreCA);
// Build a KeyManager for Client auth
KeyManagerFactory kmf = KeyManagerFactory.getInstance(
        KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, null);
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
// Everytime you need your https connection, run this code
URL url = new URL("https://my-router:1279/");
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.setSSLSocketFactory(context.getSocketFactory());
urlConnection.setHostnameVerifier(new AllowAllHostnameVerifier());
InputStream in = urlConnection.getInputStream();