ahh! es que todo pasa en claro? yo estoy asumiendo que el Message Key pasa por asimetrico! :s
Era mi duda, yo asumo que pasa por asimetro al igual que tu y con las claves publicas Curve25519 lo decifran. En la lectura no lo especifican, me imagino que lo dan por hecho.
Bueno ya que nos quitamos la duda teóricamente todo esta bien.
Acabo de hacer un programa en C usando libgcrypt para ejemplicar esto.
El programa hace lo siguiente.
- Crea un archivo llamada AAAA.txt de 512 bytes lleno de AAAAAAAAAA's para ejempliciar el plain text.
- Genera un par de llaves RSA (Parte tardada)
- Guarda las claves creadas en archivo en archivo para su posterior uso
- Genera apartir de la llave publica y algunos otros datos 5 "Key Message" para fines didacticos solo usaremos el ultimo
- usa el campo pass del KeyMessage para cifrar el AES en modo CBC con el iv correspondiente
- Guarda la salida en un archivo llamada AAES.txt
Todavia no me queda muy claro como utilizar HMAC pero leyendo la API y los RFC correspondientes aprendere.
Muestro la salida y al final el codigo del programa que la produce.
Archivo >>>>>>>>
AAES <<<<<<<<<<<de salida
Key df9701195198737faf7c163298704e2c5b583532cf8fc20595c8512b5b65e8db2ef1683d4e7399132d719a38cdf14b32d100a73e84f338ae4d8c43dc43c408222e2278d005332bca737d55b5a7a24897
Key b858d2f07d002deeb2afd730078b8f38904725e37f98d31dd15c11a404e22777c1813ea5982db9324e9fc8f85b60720fa709f62baaab81034f9090cf4ad37609858b5d5c7b285f8f0baf241fcd405c28
Key 4df7986bfb598832b552860e7e03bb67a661c75d6a571656ac6b5e31ea60755f984964eafaf78e79e83a66589c2993dd7fc67de37467c6c3e56a565e8167305271079d6902c6cbfdd7ee8c3799d58b79
Key a8d81e45dfcec1e6cb5b9be014626311f42c38f88ceb6f4ef6494d4c7281c92c0e92cdc6cb296231322909b8634af89b15807235b7fcd27c7103e4df89e6163cf809a342ce4004145e3d7f19643d2133
Key 420341bb215e4393c4fb364ed05331bb4ab51e81355d767fe7ac4fe33012c15fcc66740840cc8b0981a9d6e98b925f408e9c16e0b559993b368fb749f337bae3dfe9797fdced844f1d227dbce12bda05
Algunas funciones del programa fueron implementadas de forma rapida y puede fallar.
/*
twitter: @albertobsd
cc -o ejemplos ejemplos.c `libgcrypt-config --cflags --libs`
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<gcrypt.h>
void libgcrypt_init();
int createRSA_4096(char *prefix,char *bufferPkey);
unsigned char *my_kdf(char *passphrase,size_t passphraselen,unsigned int iterations,size_t keysize);
int encrypt(char *buffer,char *pass,char *iv,int length);
typedef struct str_KeyMessage {
unsigned char pass[32];
unsigned char hmac[32];
unsigned char iv[16];
}*KeyMessage;
int main() {
FILE *archivo = NULL;
char *buffer = NULL;
char *pkey = NULL;
char *digest = NULL;
unsigned char *key = NULL;
int length,i,j;
if(!buffer) {
}
archivo
= fopen("AAAA.txt","w"); if(!archivo) {
}
libgcrypt_init();
length = createRSA_4096("UsuarioA",pkey);
j = 0;
while(j < 5) {
key = my_kdf(pkey,length,1024,80);
if(!key) {
}
i = 0;
while(i < 80) {
i++;
}
j++;
}
KeyMessage km = (KeyMessage)key;
encrypt(buffer,(char*)km->pass,(char*)km->iv,512);
archivo
= fopen("AAES.txt","w"); if(!archivo) {
}
}
void libgcrypt_init() {
if(!gcry_check_version(GCRYPT_VERSION)) {
fprintf(stderr
,"libgrypt version mismatch %s\n",GCRYPT_VERSION
); }
gcry_control(GCRYCTL_SUSPEND_SECMEM_WARN);
gcry_control(GCRYCTL_INIT_SECMEM,1638,0);
gcry_control(GCRYCTL_INITIALIZATION_FINISHED,0);
if(!gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P)) {
fprintf(stderr
,"libgrypt has not been initialized\n"); }
}
int createRSA_4096(char *prefix,char *publickey) {
FILE *p;
FILE *s;
gcry_sexp_t rsa_parms = NULL;
gcry_sexp_t rsa_keypair = NULL;
gcry_sexp_t rsa_skey = NULL;
gcry_sexp_t rsa_pkey = NULL;
gcry_error_t err = 0;
int temp = 0;
char *nombre_p,*nombre_s;
size_t length = 2048;
size_t offset = 0;
char *bufferkey;
err = gcry_sexp_build(&rsa_parms, NULL, "(genkey (rsa (nbits 4:4096)(rsa-use-e 1:1)))");
if(err) {
fprintf(stderr
,"gcry_sexp_build: failed to build\n"); }
err = gcry_pk_genkey(&rsa_keypair, rsa_parms);
gcry_sexp_release(rsa_parms);
if(err) {
fprintf(stderr
,"gcry_pk_genkey: failed to genkey\n"); }
rsa_pkey = gcry_sexp_find_token(rsa_keypair, "public-key", 0);
rsa_skey = gcry_sexp_find_token(rsa_keypair, "private-key", 0);
gcry_sexp_release(rsa_keypair);
bufferkey
= calloc(length
,sizeof(char)); if(bufferkey == NULL) {
fprintf(stderr
,"unable to alloc memory\n"); }
offset = gcry_sexp_sprint(rsa_pkey,GCRYSEXP_FMT_CANON,bufferkey,length);
gcry_sexp_release(rsa_pkey);
if(p == NULL) {
fprintf(stderr
,"unable to create file\n"); }
temp = offset;
memcpy(publickey
,bufferkey
,offset
); fwrite(bufferkey
,sizeof(char),offset
,p
); offset = gcry_sexp_sprint(rsa_skey,GCRYSEXP_FMT_CANON,bufferkey,length);
gcry_sexp_release(rsa_skey);
if(s == NULL) {
fprintf(stderr
,"unable to create file\n"); }
fwrite(bufferkey
,sizeof(char),offset
,s
); return temp;
}
unsigned char *my_kdf(char *passphrase,size_t passphraselen,unsigned int iterations,size_t keysize) {
gpg_error_t err;
unsigned char *bufferkey = NULL;
char *salt = NULL;
bufferkey
= calloc(keysize
,1); gcry_randomize(salt,8,GCRY_VERY_STRONG_RANDOM);
err = gcry_kdf_derive(passphrase,passphraselen,GCRY_KDF_ITERSALTED_S2K,GCRY_MD_SHA512,salt,8,iterations,keysize,bufferkey);
if(err != 0) {
return NULL;
}
else {
return bufferkey;
}
}
int encrypt(char *buffer,char *pass,char *iv,int length) {
gcry_error_t err = 0;
gcry_cipher_hd_t aes_hd;
gcry_cipher_open(&aes_hd, GCRY_CIPHER_AES256,GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_SECURE);
err = gcry_cipher_setkey(aes_hd, pass, 32);
if (err) {
fprintf(stderr
,"gcry_cipher_setkey(): could not set cipher key\n"); }
err = gcry_cipher_setiv(aes_hd, iv, 16);
if (err) {
fprintf(stderr
,"gcry_cipher_setiv(): could not set cipher initialization vector\n"); }
err = gcry_cipher_encrypt(aes_hd, (unsigned char*) buffer, length, NULL, 0);
if (err) {
fprintf(stderr
,"gcry_cipher_encrypt(): unable to encrypt file\n"); }
err = gcry_cipher_reset(aes_hd);
gcry_cipher_close(aes_hd);
return err;
}