Muy buen dia, este sera un pequeño taller para entender un poco mas sobre criptografía paso a paso usando lenguaje C y la libreria Libgcrypt.
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.
Si bien no entrare en algunos de los detalles de libgcrypt eso queda a tarea del lector.
La funcion anterior solo genera una cadena en formato S-expresion con instrucciones para posteriormente generar un par de claves:
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:
Veamos informamos de cuanta memoria se uso para el buffer y acontinuacion vemos una cadena similar a la que le pasamos al programa:
por ejemplo:
6:genkey <-6 bytes
3:rsa <- 3bytes
5:nbits <- 5 bytes
4:4096 <- 4 bytes
etc...
Generamos la clave:
La guardamos en un buffer con memoria previamente reservada:
La imprimimos en pantalla
pero bien la salida al parecer esta trunca:
Para esto guardamos el buffer completo en un archivo:
Y si revisan el contenido del archivo veran
el formato completo de las claves en el formato descrito en la documentacion de libgcrypt
https://gnupg.org/documentation/manuals/gcrypt/RSA-key-parameters.html#RSA-key-parameters
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 (c) [Seleccionar]
/*
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) {
fprintf(stderr,"gcrypt: failed initialization");
exit(0);
}
err = gcry_sexp_build(&rsa_parms, NULL, "(genkey (rsa (nbits 4:4096)(rsa-use-e 1:1)))");
if (err) {
fprintf(stderr,"gcrypt: failed initialization");
exit(0);
}
length = gcry_sexp_sprint(rsa_parms,GCRYSEXP_FMT_CANON,NULL,0);
buffer = calloc(length,sizeof( char));
offset = gcry_sexp_sprint(rsa_parms,GCRYSEXP_FMT_CANON,buffer,length);
printf("Buffer size %i\n",length);
printf("Buffer offset %i\n",offset);
printf("%s\n",buffer);
memset(buffer,0,length);
err = gcry_pk_genkey(&rsa_keypair, rsa_parms);
if (err) {
fprintf(stderr,"gcrypt: failed initialization");
exit(0);
}
length = gcry_sexp_sprint(rsa_keypair,GCRYSEXP_FMT_CANON,NULL,0);
buffer = realloc(buffer,length*sizeof(char));
offset = gcry_sexp_sprint(rsa_keypair,GCRYSEXP_FMT_CANON,buffer,length);
printf("Buffer size %i\n",length);
printf("Buffer offset %i\n",offset);
printf("%s\n",buffer);
f = fopen("clave.txt","w");
if(f) {
fwrite(buffer,sizeof(char),offset,f);
fclose(f);
}
memset(buffer,0,length);
free(buffer);
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 (c) [Seleccionar]
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 (c) [Seleccionar]
"(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 [Seleccionar]
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 (c) [Seleccionar]
gcry_pk_genkey(&rsa_keypair, rsa_parms);
La guardamos en un buffer con memoria previamente reservada:
Código (c) [Seleccionar]
offset = gcry_sexp_sprint(rsa_keypair,GCRYSEXP_FMT_CANON,buffer,length);
La imprimimos en pantalla
Código (c) [Seleccionar]
printf("%s\n",buffer);
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:
Para esto guardamos el buffer completo en un archivo:
Código [Seleccionar]
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