anterior índice siguiente

Creacion completa de un certificado

Pero ya está bien de observar diferentes aspectos individuales de los certificados. Lo que queremos es hacer un certificado de pies a cabeza nosotros mismos, así que hemos de comenzar por tener una autoridad certificadora o ser nosotros mismos, es decir, generar un certificado autofirmado. Vamos a realizar esto último pues es lo más común si no queremos gastarnos el dinero en el certificado de una autoridad de pago para asegurar la confidencialidad de nuestro grupillo de amigos ;-). Una parte importante dentro del proceso de creación de un certificado es la firma que realiza la autoridad certificadora sobre el certificado, para ello se usa la siguiente función:

donde EVP_MD * es el nombre de alguno de los algoritmos de firma usados (y cargados) por openssl. Por ejemplo, se pude firmar con EVP_md5().
A la hora de manipular nombres openssl utiliza una doble estructura, dentro del método ASN1. Por una parte, se usa la estructura X509_NAME como almacén de un conjunto de elementos básicos de nombres, los X509_NAME_ENTRY. La forma más sencilla de poner nombres sin tener que entrar en detalles de la libreria ASN1 es usa el método de inserción por texto. A partir de un nombre de elemento dentro del conjunto de X509_NAME, podemos asignarle un valor. Para ello usamos la siguiente función: La secuencia completa para crear un certificado desde el inicio es el siguiente:
  1. Iniciación de las variables oportunas (variable de clave pública, certificado, clave rsa, estructuras de nombres, ficheros, etc.).
  2. Generación de un par de claves RSA del tamaño que queramos (1024 bits suele ser una buena elección).
  3. Asignación del par RSA a la estructura de clave pública EVP_PKEY.
  4. Relleno de campos de número de versión, de serie y fechas de validez(desde el momento actual y por un año es una buena opción).
  5. Obtención y relleno de la estructura de nombres del certificado, tanto para el subject como para el issuer (si lo hacemos autofirmado).
  6. Firma del certificado.
  7. Escritura de la clave privada y del certificado.


// En este ejemplo vamos a crear un certificado completo autofirmado.
// La sintaxis es:
// 		cert_completo fich_cert fich_key numbitsRSA numserie dias_valido
//
//		fich_cert   : Nombre del fichero de salida del certificado X509
//		fich_key    : Nombre del fichero de salida de la clave privada
//		numbitsRSA  : Numero de bits de las claves RSA 
//		numserie    : Numero de serie del certificado
//		dias_valido : Numero de dias de validez del certificado 
//
// Ejemplo creado por Jose Traver - jose@nisu.org

#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <stdio.h>
#include <stdlib.h>

int main (int argc, char ** argv)
{
   FILE * fp_cert,*fp_clave;
   X509 * x=NULL;
   EVP_PKEY * clave=NULL;
   RSA * rsa;
   X509_NAME * nombre=NULL;
   int Nserie;
   int Nrsa;
   int Ndias;   


   // Abrimos el fichero para escritura del certificado

    if ((fp_cert =fopen(argv[1],"w")) == NULL) {
        perror("ERROR al abrir el fichero del certificado");
        exit(1);
   }
   
   // Abrimos el fichero para escritura de la clave privada

    if ((fp_clave =fopen(argv[2],"w")) == NULL) {
        perror("ERROR al abrir el fichero de la clave privada");
        exit(1);
   }

   // Recogida de datos de los parametros

   Nserie = atoi(argv[4]);
   Nrsa = atoi(argv[3]);
   Ndias = atoi(argv[5]);

   // Iniciación de variables y estructuras del programa

   x = X509_new();
   clave = EVP_PKEY_new();

   // Generación del par de llaves RSA

   rsa=RSA_generate_key(Nrsa,RSA_F4,NULL,NULL);

   // Asignación del par RSA a la estructura de clave privada EVP_PKEY

   EVP_PKEY_assign_RSA(clave,rsa);

   // Relleno de datos del certificado

   X509_set_version(x,3);
   ASN1_INTEGER_set(X509_get_serialNumber(x),Nserie);
   X509_gmtime_adj(X509_get_notBefore(x),0);
   X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*Ndias);
   X509_set_pubkey(x,clave);

   // Relleno de nombres del certificado. Esto podria hacerse de varias formas:
   // 		* Interactuando con el usuario
   // 		* Leyendo la información de un fichero
   // Ya que es solo un ejemplo, los ponemos a mano y vale, pero el sistema es
   // bien sencillo, solo se necesita obtener cadenas de caracteres.

   nombre=X509_get_subject_name(x);
   X509_NAME_add_entry_by_txt(nombre,"C",MBSTRING_ASC, "ES", -1, -1, 0);
   X509_NAME_add_entry_by_txt(nombre,"ST",MBSTRING_ASC, "CS", -1, -1, 0);
   X509_NAME_add_entry_by_txt(nombre,"L",MBSTRING_ASC, "Cs", -1, -1, 0);
   X509_NAME_add_entry_by_txt(nombre,"O",MBSTRING_ASC, "Mi organizacion", -1, -1, 0);
   X509_NAME_add_entry_by_txt(nombre,"OU",MBSTRING_ASC, "Mi departamento", -1, -1, 0);
   X509_NAME_add_entry_by_txt(nombre,"CN",MBSTRING_ASC, "Mi nombre", -1, -1, 0);
   X509_NAME_add_entry_by_txt(nombre,"Email",MBSTRING_ASC, "nombre@dir.dom", -1, -1, 0);

   X509_set_issuer_name(x,nombre);

   // Firmamos el certificado que hemos creado con nuestra propia clave

   X509_sign(x,clave,EVP_md5());

   // Podemos imprimir por pantalla el resultado del certificado y la clave

   RSA_print_fp(stdout,clave->pkey.rsa,0);
   X509_print_fp(stdout,x);

   // Escribimos el certificado y la clave privada en los ficheros especificados

   PEM_write_X509(fp_cert,x);
   PEM_write_PrivateKey(fp_clave,clave,NULL,NULL,0,NULL, NULL);

   // Cerramos ficheros y liberamos de la memoria las estructuras usadas

   fclose(fp_cert);
   fclose(fp_clave);
   X509_free(x);
   EVP_PKEY_free(clave);

}
   

Ejemplo 10. Creación de un certificado X509 autofirmado


anterior índice siguiente