Aug 01

Extracting private and public keys from a p12 file

Reading time: 1 – 2 minutes

PKCS#12 is a container for storing many cryptography objects as a single file. It is commonly used to bundle a private key with its X.509 certificate or to bundle all the members of a chain of trust. This is a fast and simple summary about how to extract your keys from those kind of files:

#Private key:
openssl pkcs12 -in file_name.p12 -nocerts -out private.key
#Certificates:
openssl pkcs12 -in file_name.p12 -clcerts -nokeys -out public.crt

Recurrently I have to access to a usuful guide about those kind of openssl parameters, let me refer that guide:

The Most Common OpenSSL Commands (local copy)

Update 2016/09/19
Usefull links for SSL:

Jun 17

openssl: certificats autosignats de forma molt simple

Reading time: 2 – 4 minutes

Fins aquest matí cada vegada que necessitava crear-me certificats auto-signats (self-signed certificates) usava llarguíssimes llistes d’opcions amb l’openssl, però avui he descobert (digueu-me lent) que si descarregues el paquet d’OpenSSL i el desempaquetes dins del codi font hi ha un directori que es diu: easy-rsa.

Com es pot observar el nom ja dona moltes pistes, doncs bé, dintre d’aquest hi trobem encara un altre directori anomenat 2.0. Aquí dintre, hi ha un munt d’scripts que ens simplificaran moltíssim la vida a l’hora de crear certificats, com sempre en faig un resum en forma de cookbook.

  • Editar el fitxer vars. Cal modificar el valor de les variables:
  • export KEY_COUNTRY="yourContry"
    export KEY_PROVINCE="yourProvince"
    export KEY_CITY="yourCity"
    export KEY_ORG="myOwnOrg"
    export KEY_EMAIL="user@domain.tld"
  • Després netegem el directori de claus perquè no hi hagi restes d’exemples:
  • ./clean-all
  • Carreguem variables d’entorn del fitxer vars:
  • source ./vars
  • Creem una CA (Certificate Authority):
  • ./pkitool --initca
  • Crear el certificat per un servidor:
  • # ./pkitool --server
    # penseu que a vegades el common_name ha de ser el url_host del servidor, per exemple, en servidors https
    ./pkitool --server nom_servidor
  • Certificats per un client:
  • # ./pkitool
    ./pkitool nom_client
  • Certificat per un client enpaquetat amb PKCS12:
  • # ./pkitool --pkcs12
    ./pkitool --pkcs12 nom_client
  • Generar un fitxer DH (Diffie-Hellman)
  • ./pkitool --build-dh

NOTA: en cas de volgueu protegir les claus privades amb una clau simètrica per evitar que siguin usades per tercers persones podeu fer-ho afegint el paràmetre ‘–pass‘ a les comandes anteriors.

Les claus generades les podeu trobar al directori ‘easy-rsa/2.0/keys‘.

Pels que no tingueu massa per la mà el tema dels certificats posaré quatre notes sobre els fitxers creats:

  • *.csr: Certificate Signing Request, petició de certificat que s’envia a una CA perquè ens el torni signat.
  • *.crt: Certificat signat per una CA
  • *.key: Clau privada del certificat, sovint s’acostuma a protegir amb una clau simètrica
  • ca.crt: Certificat de la CA
  • ca.key: clau privada del certificat de la CA.

Senzill, oi? diria que ja no teniu excusa per gestionar-vos vosaltres mateixos les claus SSL. Si ús calen d’altres funcions al directori esmentat hi ha molts altres scripts i el propi ‘pkitool‘, té força altres opcions molt interessants i igual de simples d’usar.

Jun 16

openssl: canvi de clau privada d’un PKCS12

Reading time: 1 – 2 minutes

Pels que ús soni de res el PKCS12 la wikipedia és un bon lloc per coneixer de que va, una definició xapussera de què conté un PKCS12 seria:

  • Cert de la CA (Certificate Authority)
  • Cert del client
  • Clau privada del client

Això permet poder configurar ràpidament clients que han d’usar certificats ja que només tenim un fitxer que posar a la configuració.

A continuació enganxo un petit cookbook que explica com canviar o treure la clau simètrica que protegeix la clau privada del certificat client:

#extreiem private key d'un p12
openssl pkcs12 -in client.p12 -nocerts -out client_private_key.pem
#extreiem client certificate d'una p12
openssl pkcs12 -in client.p12 -clcerts -nokeys -out client_cert.pem
#extreiem CA d'una p12
openssl pkcs12 -in client.p12 -cacerts -nokeys -out ca_cert.pem
#treiem password d'una clau
openssl rsa -in client_private_key.pem -out client_private_key.nopass.pem
#canvi pass d'una clau
openssl rsa -in client_private_key.pem -des3 -out client_private_key.novaclau.pem
#creem una p12 a partir dels seus fitxers arrel
openssl pkcs12 -export -out client.nou.p12 -in client_cert.pem -inkey client_private_key.novaclau.pem -certfile ca_cert.pem -name "nova clau" -out client.nou.p12
Oct 18

sslproxy

Reading time: 2 – 4 minutes

L’sslproxy és una petita eina d’aquelles que van de PM… què fa doncs el nom ho diu tot:

SSL Proxy server listens on a TCP port, accepts SSL connections, and forwards them to another local or remote TCP port. For example, it is possible to create an HTTPS server if you have an HTTP server and you run an SSL Proxy server on port 443 which forwards the connections to port 80. SSL Proxy’s design makes it as secure as possible and still perform well.

Un petit exemple on es pot veure com funciona. Llencem una petició HTTPs des del nostre navegador contra l’sslproxy i aquest re-enviarà la petició a un servidor TCP (netcat) i podrem veure la browser fingerprint del nostre navegador. O dit més senzill, la petició HTTP del nostre navegador, sense la S. O sigui, sense l’SSL.

Posem el servidor TCP (netcat) a escoltar el port 8000:

nc -l p 8000

Llencem el sslproxy amb el seu certificat SSL corresponent:

ssl_proxy -s 443 -d -c 8000 -C server-cert.pem -K server-key.pem

Anem al navegador i la barra de direcció posem:

https://localhost

Si mirem el nc podrem veure que hi ha la petició HTTP que llençavem:

GET / HTTP/1.0
Host: localhost
Accept: text/html, text/plain, application/vnd.sun.xml.writer, application/vnd.sun.xml.writer.global, application/vnd.stardivision.writer, application/vnd.stardivision.writer-global, application/x-starwriter, application/vnd.sun.xml.writer.template
Accept: application/msword, application/vnd.sun.xml.calc, application/vnd.stardivision.calc, application/x-starcalc, application/vnd.sun.xml.calc.template, application/excel, application/msexcel, application/vnd.ms-excel, application/x-msexcel
Accept: application/vnd.sun.xml.impress, application/vnd.stardivision.impress, application/vnd.stardivision.impress-packed, application/x-starimpress, application/vnd.sun.xml.impress.template, application/powerpoint, application/mspowerpoint
Accept: application/vnd.ms-powerpoint, application/x-mspowerpoint, application/vnd.sun.xml.draw, application/vnd.stardivision.draw, application/x-stardraw, application/vnd.sun.xml.draw.template, application/vnd.sun.xml.math
Accept: application/vnd.stardivision.math, application/x-starmath, text/sgml, video/mpeg, image/jpeg, image/tiff, image/x-rgb, image/png, image/x-xbitmap, image/x-xbm, image/gif, application/postscript, */*;q=0.01
Accept-Encoding: gzip, compress
Accept-Language: en
User-Agent: Lynx/2.8.5rel.1 libwww-FM/2.14 SSL-MM/1.4.1 OpenSSL/0.9.7e

L’exemple és una mica xorra a nivell funcional, però crec que a nivell conceptual és molt explicit de quina és la funcionalitat que ens ofereix el sslproxy. Sobretot si hem programat una aplicació que no té suport SSL i li volem afegir seria tan senzill com aplicar el que explico aquí.

Oct 02

HTTPs, SSL i Certificats en Servidor i Client – Webs privades amb una C.A.

Reading time: 12 – 20 minutes

Com podeu veure aquest post té un parell de títols i suposo que seria molt senzill tenir-ne molts més. Així doncs intentaré descriure la idea del que després explicaré. El que pretenc fer parlant sense tecnisismes és disposar d’un servidor web que només sigui accesible de forma irrefutable i segura pels clients (navegadors) que nosaltres permetem. Això és útil per exemple per bancs, institucions, etc. tot i que en el meu cas és simplement per donar serveis via web als que només tingui accés gent controlada.

key.jpg

Per tal de montar això el que hem de fer és primer de tot montar una entitat de certificació, a la que anomenarem CA (Certifcate Authority). Això ens permetrà emetre tans certificats com volguem tan per servidors com per clients. De fet, perquè això es reconegui publicament només ens caldria que els certificats es signessin per una SA (Signing Authority) o autoritat de confiança. Perquè sapigueu de què parlo alguns exemples d’autoritats d’aquest tipus són: Baltimore, RSA, VeriSign i Thawte. De fet, si volem nosaltres mateixos podem fer d’SA el que no tindrem és la confiança de tercers, ja que no ens reconeixeran com a TA (Trust Authority). Però pel nostre exemple no ens cal així doncs nosaltres mateixos ens ho farem tot.

De fet, tota aquesta història de les entitats de certificació és molt més complexe, però nosaltres només arribarem fins on ens interessa. Intentant simplificar al màxim. Tampoc cal que ens montem una PKI (Public key infrastructure) professional per treballar amb algo tan senzillet. Així doncs, ja tenim clar que hem de montar una CA (root CA) que emetrà emetrà certificats signats per ella mateixa (self-signed certificate). Aquests certificats podràn ser usats per servidors i clients. Així doncs, si montem un servidor que usi aquest certificat podem fer que aquest requereixi que els clients disposin d’un certificat en mode client sinó no podran accedir al servei oferit.

Pel cas que ens interessa el que farem és montar un servidor web, Apache concretament, que només podrà ser accedit pels clients (firefox, netscape, MSIE, etc) que disposin del certificat corresponent.

Què necessitem per montar la CA?

Només cal que tingueu instal·lat el OpenSSL, jo com sempre uso Gentoo i el paquet que he usat és dev-libs/openssl-0.9.7e-r1. El fitxer de configuració més important d’aquest paquet està a /etc/ssl/openssl.cnf. Jo l’he modificat conretament on diu default_days = 365 he canviat el 365 per 3650 així els meus certificats encomptes de ser vigents durant un any seràn vigents durant 10 anys. Si voleu això també es pot alterar a través de la línia de comandes al llençar l’script CA.pl amb el paràmetre -days.

Com ja vaig comentar a l’article: Xarxa Wifi Segura: freeRadius + WRT54G = 802.1x (WPA-radius EAP/TLS), on també s’havia de montar una entitat de certificació la distribució gentoo no instal·la el fitxer CA.pl per defecte i pot ser que no el troveu pel vostre sistema després d’instal·lar el openSSL. Així doncs, jo el que he fet és descomprimir el paquet d’openssl i truere el fitxer directament d’allà i després me l’he copiat a un directori on treballaré a partir d’ara: ~/CA.

Creem la C.A. arrel (root CA)

Un cop dins de ~/CA per generar el certificat de l’entitat arrel (root CA) només cal que feu: perl CA.pl -newca.

$ perl CA.pl -newca
CA certificate filename (or enter to create)
Making CA certificate ...
Generating a 1024 bit RSA private key
......................++++++
.............++++++
writing new private key to './demoCA/private/cakey.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
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) [AU]:ES
State or Province Name (full name) [Some-State]:BCN
Locality Name (eg, city) []:BCN
Organization Name (eg, company) [Internet Widgits Pty Ltd]:example CA authority
Organizational Unit Name (eg, section) []:example
Common Name (eg, YOUR name) []:example CA
Email Address []:example@example.com

Veureu que es crea un directori que es diu demoCA i dintre hi ha el fitxer cacert.pem que és el certificat de la nostre root CA.

Emetem un certificat amb la nostre root CA

Primer el que fem és una petició de certificat (request): perl CA.pl -newreq.

$ perl CA.pl -newreq
Generating a 1024 bit RSA private key
...................++++++
.................................................++++++
writing new private key to 'newreq.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
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) [AU]:ES
State or Province Name (full name) [Some-State]:BCN
Locality Name (eg, city) []:BCN
Organization Name (eg, company) [Internet Widgits Pty Ltd]:example company
Organizational Unit Name (eg, section) []:example e-comerce department
Common Name (eg, YOUR name) []:www.example.com
Email Address []:example@example.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Request (and private key) is in newreq.pem

Obtenim el fitxer: newreq.pem. Fixeu-vos que aquest certificat és pel servidor www.exemple.com. Si voleu emetre un certificat per qualsevol subdomini del domini exmemple.com, podeu posar a ‘Common Name’ el següent *.exemple.com. El que no he provat és posar * a veure si així funciona per qualsevol domini. Tot i que jo diria que no ha de funcionar, sinó el certificat no garintiria que el servidor és qui diu ser.

Signem el certificat emès

Aquest pas és el que hauriem de demanar a la entitat de confiança (TA) la qual després d’enviar-li el nostre certificat ens el tornaria signat (SA). Però que nosaltres som com el ‘joan palom’ (jo me lo guis jo me lo com) doncs ens ho farem nosaltres mateixo amb l’ordre perl CA.pl -sign:

$ perl CA.pl -sign
Using configuration from /etc/ssl/openssl.cnf
Enter pass phrase for ./demoCA/private/cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number:
            82:9d:18:98:a7:25:24:7e
        Validity
            Not Before: Oct  1 10:50:03 2005 GMT
            Not After : Oct  1 10:50:03 2006 GMT
        Subject:
            countryName               = ES
            stateOrProvinceName       = BCN
            localityName              = BCN
            organizationName          = example company
            organizationalUnitName    = example e-comerce department
            commonName                = www.example.com
            emailAddress              = example@example.com
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
                EE:8C:BC:6F:3D:3B:4D:82:56:24:BB:76:E8:39:F3:23:F3:BD:C9:BF
            X509v3 Authority Key Identifier:
                keyid:EE:71:7F:C0:71:39:F1:8A:70:B4:BC:BB:F0:48:B2:77:58:E4:F6:AE
                DirName:/C=ES/ST=BCN/L=BCN/O=example/OU=example/CN=example/emailAddress=example@example.com
                serial:82:9D:18:98:A7:25:24:7D
Certificate is to be certified until Oct  1 10:50:03 2006 GMT (365 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
Signed certificate is in newcert.pem

Ara ja tenim signat el newreq.pem dins del fitxer newkey.pem. A continuació el que farem és extreure la clau privada que hi ha dins del fitxer newkey.pem:

$ openssl rsa < newreq.pem > newkey.pem
Enter pass phrase:
writing RSA key

A newkey.pem hi ha la clau privada del ‘request’.

Renombrem els fitxer per aclarir les coses

Per tal de simplificar una mica tots els conceptes és una bona idea renombrar els fitxers que hem generat:

newcert.pem -> server_cert.pem: certificat signat pel nostre servidor. Això ens permetrà després crear la clau del client.
newkey.pem -> server_key.pem: clau privada (xifrada) en format de texte pla necessaria pel certificat del servidor. La clau privada és la part secreta del certificat, hem d'evitar que tercers la puguin aconseguir.
newreq.pem -> server_req.pem: clau privada xifrada i la petició de certificat original.

Creem el certificat pel client en format pkcs12

Resulta que els nostres navegadors volen els certificats de client en un format que es diu pkcs12 (Personal Information Exchange Syntax Standard) així doncs som-hi:

# openssl pkcs12 -export -in server_cert.pem -inkey server_key.pem -out iestuff.p12
Enter Export Password:
Verifying - Enter Export Password:

Aquí també podria haver canviat el nom del fitxer on es guarda la clau i no posar-li iestuff.p12 com els exemples en que m’he basat, però la mandra és el que té. Bé doncs, ja tenim el nostre fitxer pkcs12: iestuff.p12.

Instal·lem el certificat a l’apache

No us ho creureu però he trigat més estona en fer això que en tota la resta i mira que és senzill, però he aprofitat per actualitzar el servidor i resulta que el nou paquet d’apache per gentoo funciona diferent que l’anterior i no trobava res de res. A partir d’ara parlaré doncs de com fer això en net-www/apache-2.0.54-r31. Però donaré un apunt per estalviar temps als que no useu gentoo.

L’apunt l’únic que s’ha de fer és posar els detalls necessaris perquè funcioni el vostre servidor apache amb SSL i dels fitxers de configuració d’apache només heu de modificar el ‘VirtualHost’ que necessitarà el certificat. Així doncs a partir d’ara el que toca és veure la destresa de cada un amb les infitintes ordres que té l’apache pels seu fitxer de configuració.

NOTA IMPORTANT PER TOTHOM: no oblideu que quan treballem amb un VirtualHost dins de l’espai de configuració del mateix cal user el paràmetre ServerName; doncs bé el que poseu aquí ha de coincidir al 100% amb el que posa al ‘Common Name’ del certificat que heu emès. A més, el vostre DNS ha de resoltre el mnemònic que hagiu usat amb la IP del servidor sinó no funcionarà, a més el nom ha de ser un registre de tipus A i no un CNAME dins la configuració del DNS.

Bé doncs en el paquet de gentoo que comentat el que he fet és modificar el fitxer de configuració del host SSL per defecte, això es fa al fitxer: /etc/apache2/modules.d/41_mod_ssl.default-vhost.conf. Per llençar l’apache amb el host SSL per defecte s’ha de tocar el /etc/conf.d/apache2 perquè es llenci amb les opcions: -D SSL i -D SSL_DEFAULT_VHOST. Amb això el fitxer de configuració 41_mod_ssl.default-vhost.conf passa a tenir validesa. Aqust fitxer l’he modificat ben poc només perquè apunti on he copiat els certificats.

Fixer 41_mod_ssl.default-vhost.conf:

<IfDefine SSL>
  <IfDefine SSL_DEFAULT_VHOST>
<IfModule mod_ssl.c>
<VirtualHost *:443>
DocumentRoot "/var/www/localhost/htdocs"
ServerName www.exemple.com
ServerAdmin root@localhost
ErrorLog logs/ssl_error_log
<IfModule mod_log_config.c>
        TransferLog logs/ssl_access_log
</IfModule>41_mod_ssl.default-vhost.conf
SSLEngine on
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
SSLCertificateFile /etc/apache2/ssl/server_cert.pem
SSLCertificateKeyFile /etc/apache2/ssl/server_key.pem
SSLCACertificatePath /etc/apache2/ssl/
SSLCACertificateFile /etc/apache2/ssl/cacert.pem
SSLVerifyClient require
SSLVerifyDepth  2
	<Files ~ "\.(cgi|shtml|phtml|php?)$">
    SSLOptions +StdEnvVars
</Files>
	<Directory "/var/www/localhost/cgi-bin">
    SSLOptions +StdEnvVars
</Directory>
	<IfModule mod_setenvif.c>
    SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown \
    downgrade-1.0 force-response-1.0
</IfModule>
	<IfModule mod_log_config.c>
CustomLog logs/ssl_request_log \
          "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</IfModule>
	<IfModule mod_rewrite.c>
RewriteEngine On
RewriteOptions inherit
</IfModule>
	</VirtualHost>
	</IfModule>
	</IfDefine>
</IfDefine>

He tret els comentaris que porta el fitxer perquè no es fassi tan llarg. Però la part més important us la comento a continuació:

ServerName www.exemple.com
SSLCertificateFile /etc/apache2/ssl/server_cert.pem
SSLCertificateKeyFile /etc/apache2/ssl/server_key.pem
SSLCACertificatePath /etc/apache2/ssl/
SSLCACertificateFile /etc/apache2/ssl/cacert.pem
SSLVerifyClient require
SSLVerifyDepth  2

La primera línia és la nota que us he posat abans sobre el ServerName, o sigui, posar-lo igual que el ‘Common Name’ del certificat. El certificat signat del servidor SSLCertificateFile, la clau privada del certificat SSLCertificateKeyFile el directori on guardem les entitats de certificació arrel (root CA) SSLCACertificatePath /etc/apache2/ssl/ i el fitxer que conté el certificat de la nostre entitat de certificació arrel SSLCACertificateFile.

Les últimes dues línies són les més interessants: SSLVerifyClient indiquem si cal que el client tingui o no tingui certificat. En aquest cas requerim que el client tingui certificat per funcionar. Finalment a la última línia indiquem quina és la tolerància que donem als certificats que acceptem. És a dir, fins a quina profunditat confiem amb les entitats que poden haver emès aquest certificat. Diguem que és un tecnisisme d’herència entre entitats de confiança jo hi he posat un 2 però podeu posar-hi qualsevol número >1 i funcionarà sense problemes.

Configuració del client

Aquí només us comento com es fa amb el firefox, però amb el MSIE i el Netscape es fa quasi igual, segur que us en sortiu. Jo no només he afegit el certificat client que seria el normal sinó també el certificat de la entitat arrel (root CA) així el navegador no em pregunta cada vegada si ha de confiar amb el certificat que rep d’una root CA que no coneix.

Anem al menú Edit -> Preferences -> Advanced -> Manage Cerficates:

firefox1.png

Ara instal·lem el certificat client, anem a ‘Your Cerficates’ i premem ‘Import’ seleccionem el fitxer i importem el nostre certificat iestuff.p12:

firefox2.png

Per instal·lar el certificat del ‘root CA’ anem a la pestanya ‘Authorithies’ premem ‘Import’ i importem el fitxer cacert.pem:

firefox3.png

Conclusions

Sembla molt llarg tot el procés, però realment no ho és tan simplement que explicant sempre t’allargues més del que realment després has de fer a més he intentat ser força fidel en tot el que he fet en cada pas. Es podria haver simplificat molt més. No patiu per la part del servidor penseu que si us enganxeu el vostre problema és que coneixeu poc l’apache i d’això a tot arreu n’hi ha gent que en sap i de manuals en teniu per aburrir. Pel que fa el tema del client com podeu veure és molt senzill i si la resta esta bé funcionarà a la primera.

Enllaços

Per montar tot això he usat bàsicament dos sites que m’han ajudat moltíssim: