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

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



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