Hace poco me tocó jugar con un HSM de Thales. Esta vez me tocó firmar un certificado. La consigna era no gastar más dinero en certificados firmados por CAs conocidas.. por lo que tuve que crear una CA.

Era sencillo, pero tuvo sus particularidades. Básicamente necesitaba si o si que el certificado fuese firmado por una Sub-CA y que el certificado si o si fuese generado en versión 3.

Me embarque en la aventura de generar una CA y una Sub CA para firmar el CSR respetando las características previamente mencionadas.

Dada la letra del problema, tuve que generar la siguiente estructura:

[CA]<[Sub CA]<[Certificado firmado]

• Creación de la CA:

~]# mkdir $HOME/SSL_HSM

~]# cd $HOME/SSL_HSM

• copiamos el archivo HSM.csr a $HOME/SSL_HSM

SSL_HSM]# mkdir CA

SSL_HSM]# ls

CA HSM.csr

SSL_HSM]# cd CA

• Generamos la clave privada de nuestra CA, esto nos pedirá elegir una contraseña:

CA]# openssl genrsa -aes256 -out ca.key.pem 4096

Generating RSA private key, 4096 bit long modulus

…++

……………………………………………………………………………………………………………………….++

e is 65537 (0x10001)

Enter pass phrase for ca.key.pem: <Contras3n4>

VerifyingEnter pass phrase for ca.key.pem: <Contras3n4>

• Verificamos que esté todo OK:

CA]# openssl rsa -in ca.key.pem -check

Enter pass phrase for ca.key.pem:

RSA key ok

writing RSA key

— -BEGIN RSA PRIVATE KEY— –

MIIJKqIBAAKCAgEAoMSLrBOZaiGvlmsVnvgHNMwEqejp/CP3NWvsSu87aMY2+JT3

[..salida de Clave Privada..]

— -END RSA PRIVATE KEY— –

• Ahora creamos un certificado con esa clave privada que creamos anteriormente

CA]# 

CA]# openssl req -key ca.key.pem -new -x509 -days 1095 -sha256 -extensions v3_cat -out ca.cert.pem

Enter pass phrase for ca.key.pem: <Contras3n4>

You are about to be asked to enter information that will be incorporated

into your certificate request.

What you are about to enter is what is called a Distinguished Name or a DN.

There are quite a few fields but you can leave some blank

For some fields there will be a default value,

If you enter ‘.’, the field will be left blank.

— –

Country Name (2 letter code) [XX]:UY

State or Province Name (full name) []:Montevideo

Locality Name (eg, city) [Default City]:Montevideo

Organization Name (eg, company) [Default Company Ltd]:Qualia

Organizational Unit Name (eg, section) []:Seguridad Informatica

Common Name (eg, your name or your server’s hostname) []:qualia.uy

Email Address []:rtumaian@qualia.uy

CA]# ls

ca.cert.pem ca.key.pem

• Algunos archivos para serializar

CA]# touch certindex

CA]# echo 1000 > certserial

CA]# echo 1000 > crlnumber

• Una vez generado la CA, debemos crear el certificado Intermedio:

CA]# mkdir Intermedio

CA]# cd Intermedio/

Intermedio]# openssl genrsa -out intermediate1.key 4096

Generating RSA private key, 4096 bit long modulus

e is 65537 (0x10001)

• Ahora genero el Certificate Sign Request, para que sea firmado por el certificado de la CA root que creamos anteriormente:

Intermedio]# openssl req -new -sha256 -key intermediate1.key -out intermediate1.csr

You are about to be asked to enter information that will be incorporated

into your certificate request.

What you are about to enter is what is called a Distinguished Name or a DN.

There are quite a few fields but you can leave some blank

For some fields there will be a default value,

If you enter ‘.’, the field will be left blank.

— –

Country Name (2 letter code) [XX]:UY

State or Province Name (full name) []:Montevideo

Locality Name (eg, city) [Default City]:Montevideo

Organization Name (eg, company) [Default Company Ltd]:Qualia

Organizational Unit Name (eg, section) []:Sistemas

Common Name (eg, your name or your server’s hostname) []:Qualia Sub CA

Email Address []:rtumaian@qualia.uy

Please enter the following ‘extra’ attributes

to be sent with your certificate request

A challenge password []:PasswdD1f1c1l>

An optional company name []:

Intermedio]# ls

intermediate1.csr intermediate1.key

  • Ahora lo firmamos con nuestra CA que creamos anteriormente. Para ello vamos a definir los parámetros de configuración en un archivo:

Intermedio]# echo “

[ ca ]

default_ca = qualia.uy

[ crl_ext ]

issuerAltName=issuer:copy 

authorityKeyIdentifier=keyid:always

[ qualia.uy ]

 dir = ./

 new_certs_dir = $dir

 unique_subject = no

 certificate = $dir/../ca.cert.pem

 database = $dir/../certindex

 private_key = $dir/../ca.key.pem

 serial = $dir/../certserial

 default_days = 730

 default_md = sha1

 policy = myca_policy

 x509_extensions = myca_extensions

 crlnumber = $dir/../crlnumber

 default_crl_days = 730

# AÑO MES DIA HORA MINUTO Esto me costo darme cuenta como estaba en la documentación, al final va una Z

# Estas son las fechas de inicio y expiración

 default_enddate = 20191108000001Z

 default_startdate = 20171109000001Z

[ myca_policy ]

 commonName = supplied

 stateOrProvinceName = supplied

 countryName = optional

 emailAddress = optional

 organizationName = supplied

 organizationalUnitName = optional

[ myca_extensions ]

 basicConstraints = critical,CA:TRUE

 keyUsage = critical,any

 subjectKeyIdentifier = hash

 authorityKeyIdentifier = keyid:always,issuer

 keyUsage = digitalSignature,keyEncipherment,cRLSign,keyCertSign

 extendedKeyUsage = serverAuth

 crlDistributionPoints = @crl_section

 subjectAltName = @alt_names

 authorityInfoAccess = @ocsp_section

[ v3_ca ]

 basicConstraints = critical,CA:TRUE,pathlen:0

 keyUsage = critical,any

 subjectKeyIdentifier = hash

 authorityKeyIdentifier = keyid:always,issuer

 keyUsage = digitalSignature,keyEncipherment,cRLSign,keyCertSign

 extendedKeyUsage = serverAuth

 crlDistributionPoints = @crl_section

 subjectAltName = @alt_names

 authorityInfoAccess = @ocsp_section

[alt_names]

 DNS.0 = Qualia Intermidiate CA 1

 DNS.1 = Qualia CA Intermidiate 1

[crl_section]

 URI.0 = https://ca.qualia.uy/ca.crl

 URI.1 = https://ca-1.qualia.uy.uy/ca.crl

[ocsp_section]

 caIssuers;URI.0 = https://ca.qualia.uy.uy/ca.crt

 caIssuers;URI.1 = https://ca-1.qualia.uy.uy/ca.crt

 OCSP;URI.0 = https://ca.qualia.uy.uy/ocsp/

 OCSP;URI.1 = https://ca-1.qualia.uy.uy/ocsp/

“ > intermedio.conf

Intermedio]# ls

intermediate1.csr intermediate1.key intermedio.conf

Intermedio]# openssl ca -batch -config intermedio.conf -notext -in intermediate1.csr -out intermediate1.crt

Using configuration from intermedio.conf

Enter pass phrase for .//../ca.key.pem: <Contras3n4>

Check that the request matches the signature

Signature ok

The Subject’s Distinguished Name is as follows

countryName :PRINTABLE:’UY’

stateOrProvinceName :ASN.1 12:’Montevideo’

localityName :ASN.1 12:’Montevideo’

organizationName :ASN.1 12:’Qualia’

organizationalUnitName:ASN.1 12:’Sistemas’

commonName :ASN.1 12:’Qualia Sub CA’

emailAddress :IA5STRING:’rtumaian@qualia.uy

Certificate is to be certified until Nov 8 00:00:01 2019 GMT (730 days)

Write out database with 1 new entries

Data Base Updated

Intermedio]# ls

1001.pem intermediate1.crt intermediate1.csr intermediate1.key intermedio.conf

• En este punto tenemos una CA, y un certificado Intermedio, el cual fue firmado por la CA. Ahora nos queda firmar el CSR con nuestro certificado Intermedio.

Intermedio] # mkdir HSM

HSM]# cd HSM

HSM]# mv ../../../HSM.csr .

• Debemos agregar la extensión para que el certificado sea generado en versión 3, sino el HSM lo rechazará.

HSM]# echo “authorityKeyIdentifier=keyid,issuer

basicConstraints=CA:FALSE

keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment” > v3.ext

HSM]# openssl x509 -req -days 360 -in HSM.csr -extfile v3.ext -CA ../intermediate1.crt -CAkey ../intermediate1.key -CAcreateserial -out HSM.crt -sha256

Signature ok

subject=/C=uy/ST=Montevideo/L=Montevideo/O=Qualia/OU=Sistemas/CN=B4665310608S/emailAddress=info-sisy\x7Ftemas@qualia.uy

Getting CA Private Key

HSM]# ls

HSM.crt HSM.csr v3.ext

• Ahora tenemos todos los archivos necesarios para cargar el HSM, de todas maneras vale la pena verificar si quedó todo OK:

HSM]# openssl verify -CAfile ../../ca.cert.pem -untrusted ../intermediate1.crt HSM.crt 

HSM.crt: OK

Ese OK dice que salió todo sobresaliente 🙂

Sumo también unos comandos que me fueron bastante útiles en todo momento:

Revisión de certificado:

openssl x509 -in server.crt -text -noout

Revision de clave privada:

openssl rsa -in server.key -check

Revision de CSR:

openssl req -text -noout -verify -in server.csr

Bueno, eso fue básicamente la experiencia de crear una CA y una Sub CA, hay bastante más para profundizar, pero de momento logra resolver este tema puntual.

Saludos,
Rodrigo

Leave a comment

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *