I am using OpenSSl in DevC. I was having a problem programming the PBKDF. A person suggested that I use the default function called PKCS5_PBKDF2_HMAC . I have visited many links online but cannot get this to work.My code from the main() is as follows
unsigned char pass[1024]; // passphrase read from stdin
unsigned char salt[1024]; // salt
int iter=1000, keylen=128; // iteration
unsigned char result[1024]; // result
PKCS5_PBKDF2_HMAC (pass, strlen(pass), salt, strlen(salt), iter, EVP_MD(), keylen , result);
I have just two compilation errors that are as follows:
To troubleshoot I checked the header file and also verified that I am supplying the correct parameter and in the correct order but I have no solution and I am just baffled.
You have a few major mistakes, but the idea is solid.
EVP_* needs to be a particular function.
keylen=128 is a mistake for password hashing, which your example appears to be. Don't forget - never ask for more (binary) bytes of output than the native hash function supports, because then you're doing your iteration count * (keylen / native hash size) times, and the attacker only needs to do iteration count * 1 times.
20 for SHA-1
28 for SHA-224
32 for SHA-256
48 for SHA-384
64 for SHA-512
result[1024] is far too large. result[keylen] is correct.
Watch out for buffer overflow if someone puts more than 1024 bytes in.
I have OpenSSL PBKDF2 example code in my Github repository (as well as PolarSSL and a variety of others), but the key example would be (using PBKDF2-HMAC-SHA-512, as the best of the options):
void PBKDF2_HMAC_SHA_512(const char* pass, const unsigned char* salt, int32_t iterations, uint32_t outputBytes, char* hexResult, uint8_t* binResult)
{
unsigned int i;
unsigned char digest[outputBytes];
PKCS5_PBKDF2_HMAC(pass, strlen(pass), salt, strlen(salt), iterations, EVP_sha512(), outputBytes, digest);
for (i = 0; i < sizeof(digest); i++)
{
sprintf(hexResult + (i * 2), "%02x", 255 & digest[i]);
binResult[i] = digest[i];
};
}
And it would be called by:
// 2*outputBytes+1 is 2 hex bytes per binary byte, and one character at the end for the string-terminating \0
char hexResult[2*outputBytes+1];
memset(hexResult,0,sizeof(hexResult));
uint8_t binResult[outputBytes];
memset(hexResult,0,sizeof(binResult));
PBKDF2_HMAC_SHA_512(pass, salt, iterations, outputBytes, hexResult, binResult);
Try to use SHA-384 or SHA-512 as the base hash function; they include 64-bit operations that reduce most GPU based attackers margin of advantage over you.
Use a large (hundreds of thousands to tens of thousands) number of iterations. Even larger for SHA-1.
I also have a large list of test vectors in my Github repository - you can use them to verify that your code is returning the results it should.