I need a C API in openssl library for deriving the Key from a given string. Where can i get sample source code for this?
A standard algorithm to do this is PBKDF2 (an acronym for Password-Based Key Derivation Function version 2). There is an implementation of PBKDF2 in OpenSSL, declared in openssl/evp.h
:
int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
unsigned char *salt, int saltlen, int iter,
int keylen, unsigned char *out);
When you are generating a new key you should use RAND_bytes()
from openssl/rand.h
to create the salt. iter
is the iteration count, which should be as large as your intended application can tolerate - at least something like 20,000.
I found an example on how to generate a key from a password. The example dates from 2008, as far as I can tell this is still undocumented in OpenSSL. So let me post the full example source to help all those poor souls who try to use the OpenSSL API.
Please note that this is NOT my code, it comes from Marek Marcola! All credits are due to him.
/*
* Example program on how to derive an encryption key from a password
* corresponding to the RFC2898 / PBKDF2 standard.
* Found in a 2008 mailing list posted by Marek Marcola:
* http://www.mail-archive.com/openssl-users@openssl.org/msg54143.html
*/
#include <string.h>
#include <openssl/x509.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
int print_hex(unsigned char *buf, int len)
{
int i;
int n;
for(i=0,n=0;i<len;i++){
if(n > 7){
printf("\n");
n = 0;
}
printf("0x%02x, ",buf[i]);
n++;
}
printf("\n");
return(0);
}
int main()
{
char *pass = "password";
char *salt = "12340000";
int ic = 1;
unsigned char buf[1024];
ic = 1;
PKCS5_PBKDF2_HMAC_SHA1(pass, strlen(pass), (unsigned char*)salt, strlen(salt), ic, 32+16, buf);
printf("PKCS5_PBKDF2_HMAC_SHA1(\"%s\", \"%s\", %d)=\n", pass, salt, ic);
print_hex(buf, 32+16);
ic = 1;
EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), (unsigned char*)salt, (unsigned char*)pass, strlen(pass), ic, buf, buf+32);
printf("EVP_BytesToKey(\"%s\", \"%s\", %d)=\n", pass, salt, ic);
print_hex(buf, 32+16);
return(0);
}