Hi, I'm implementing a software very similar to yours.
This is a small function that I used to generate private and public key: #include <openssl/pem.h> int main() { char * file_pem = "key_priv"; char * file_pem_pub = "key_pub"; FILE * fp; int bits = 1024; unsigned long exp = RSA_F4; RSA * rsa; rsa = RSA_generate_key(bits,exp,NULL,NULL); fp = fopen(file_pem,"w"); unsigned char* kstr ="XXXX"; //Password, change it ,it's just an example PEM_write_RSAPrivateKey(fp,rsa,EVP_des_ede3_cbc(),kstr,strlen(kstr),NULL,NULL); close(fp); fp = fopen(file_pem_pub,"w"); PEM_write_RSAPublicKey(fp,rsa); close(fp); RSA_free(rsa); } This function is called by client, it is self explicative: RSA * create_and_set_context() { RSA * rsa = RSA_new(); FILE * fp = fopen("key_pub","r"); if( fp == NULL) return NULL; RSA * rs = PEM_read_RSAPublicKey(fp, &rsa, NULL,NULL); return rs; } This is function called by client to encrypt symmetric key to send to Server. /* Key is the simmetryc key, to is a buffer */ int encrypt_simmetric_key(unsigned char *key, unsigned char *to, int size, RSA * rsa) { return RSA_public_encrypt(size, key, to, rsa, RSA_PKCS1_PADDING ); } *********************** Now, server side: RSA * create_and_set_context() { OpenSSL_add_all_algorithms(); RSA * rsa = RSA_new(); FILE * fp = fopen("key_priv","r"); unsigned char* kstr ="XXXXXX"; if( fp == NULL) return NULL; RSA * rs = PEM_read_RSAPrivateKey(fp, &rsa, NULL,kstr); return rs; } Then, supposed that buf is the buffer where is stored the symmetric key just received with a socket by Server: unsigned char* getSimKey(char * buf, RSA* rsa) { unsigned char* to = malloc(RSA_size(rsa)); // RSA_size(rsa) is the modulus if( to == NULL) return NULL; int k = RSA_private_decrypt(RSA_size(rsa), (unsigned char*)buf, to, rsa, RSA_PKCS1_PADDING); if( k == -1) return NULL; printf("K: %d\n",k); int i = 0; for(; i< k; i++) printbyte(to[i]); return to; } That's all. Sorry for my bad english, I hope my code will help. Bye Enrico