Nota para el moderador Lo pongo en Cryptografia y no en C/C++ por ver el detalle de los conceptos criptograficos.
Asi podremos observar paso paso el contenido de la memoria y como esta cambia.
Antes de programar con libgcrypt yo solo sabia los conceptos básicos de Criptografia pero en general desconocía a grandes rasgos la forma interna de trabajar de programas como GnuPG entre otros.
Los códigos que pondré aqui estan a su disposición para practicar con la librería y los conceptos criptográficos y estan disponibles en github
https://github.com/albertobsd/libgcrypt-examples
Creacion de par de Claves RSA
Bien el primer tema sera crear una clave RSA de cierta cantidad de bits y ver como esta esta clave en la memoria.
El primer ejemplo esta bajo el nombre RSA_2048.c aunque en realidad el ejmplo crea un par claves de 4096 bits
https://github.com/albertobsd/libgcrypt-examples/blob/master/RSA_2048.c
El programa genera un nuevo par de claves RSA de 4096 bits y los guarda en formato S-Expresion en un archivo llamado clave.txt por si tienen ese archivo ya existente con datos seria sobreescrito.
El codigo y luego explicare las partes interesantes por serparado.
Código
/* Twitter @albertobsd cc -o RSA_2048 RSA_2048.c `libgcrypt-config --cflags --libs` Prueba de generacion de claves RSA 2048 y 4096 bits. */ #include<stdio.h> #include<gcrypt.h> int main() { FILE *f = NULL; gcry_sexp_t rsa_parms = NULL; gcry_sexp_t rsa_keypair = NULL; gcry_error_t err = 0; char *buffer; size_t length = 4; size_t offset = 0; err = gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); err |= gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); err |= gcry_control (GCRYCTL_RESUME_SECMEM_WARN); err |= gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); if(err) { } err = gcry_sexp_build(&rsa_parms, NULL, "(genkey (rsa (nbits 4:4096)(rsa-use-e 1:1)))"); if (err) { } length = gcry_sexp_sprint(rsa_parms,GCRYSEXP_FMT_CANON,NULL,0); offset = gcry_sexp_sprint(rsa_parms,GCRYSEXP_FMT_CANON,buffer,length); err = gcry_pk_genkey(&rsa_keypair, rsa_parms); if (err) { } length = gcry_sexp_sprint(rsa_keypair,GCRYSEXP_FMT_CANON,NULL,0); offset = gcry_sexp_sprint(rsa_keypair,GCRYSEXP_FMT_CANON,buffer,length); if(f) { } gcry_sexp_release(rsa_keypair); gcry_sexp_release(rsa_parms); }
Si bien no entrare en algunos de los detalles de libgcrypt eso queda a tarea del lector.
Código
gcry_sexp_build(&rsa_parms, NULL, "(genkey (rsa (nbits 4:4096)(rsa-use-e 1:1)))");
La funcion anterior solo genera una cadena en formato S-expresion con instrucciones para posteriormente generar un par de claves:
Código
"(genkey (rsa (nbits 4:4096)(rsa-use-e 1:1)))"
Si queremos crear un par de clave de 1024 bits solo cambiaremos el 4096 por 1024 y asi susesivamente.
Si ejecutamos el programa veremos un salida similar a la siguiente:
Código:
Buffer size 49
Buffer offset 48
(6:genkey(3:rsa(5:nbits4:4096)(9:rsa-use-e1:1)))
Buffer size 2441
Buffer offset 2440
(8:key-data(10:public-key(3:rsa(1:n513:
Veamos informamos de cuanta memoria se uso para el buffer y acontinuacion vemos una cadena similar a la que le pasamos al programa:
Citar
(6:genkey(3:rsa(5:nbits4:4096)(9:rsa-use-e1:1)))
por ejemplo:
6:genkey <-6 bytes
3:rsa <- 3bytes
5:nbits <- 5 bytes
4:4096 <- 4 bytes
etc...
Generamos la clave:
Código
gcry_pk_genkey(&rsa_keypair, rsa_parms);
La guardamos en un buffer con memoria previamente reservada:
Código
offset = gcry_sexp_sprint(rsa_keypair,GCRYSEXP_FMT_CANON,buffer,length);
La imprimimos en pantalla
Código
pero bien la salida al parecer esta trunca:
Citar
Buffer size 2441
Buffer offset 2440
(8:key-data(10:public-key(3:rsa(1:n513:
Buffer offset 2440
(8:key-data(10:public-key(3:rsa(1:n513:
Para esto guardamos el buffer completo en un archivo:
Código:
fwrite(buffer,sizeof(char),offset,f);
Y si revisan el contenido del archivo veran el formato completo de las claves en el formato descrito en la documentacion de libgcrypt
Citar
(private-key
(rsa
(n n-mpi)
(e e-mpi)
(d d-mpi)
(p p-mpi)
(q q-mpi)
(u u-mpi)))
(public-key
(rsa
(n n-mpi)
(e e-mpi)))
+ Otros datos
https://gnupg.org/documentation/manuals/gcrypt/RSA-key-parameters.html#RSA-key-parameters