pbkdf2 算法 C语言实现,[求助]求PBKDF2 SHA-512算法的c/c++实现源码

/*

* lib/crypto/pbkdf2.c

*

* Copyright 2002 by the Massachusetts Institute of Technology.

* All Rights Reserved.

*

* Export of this software from the United States of America may

* require a specific license from the United States Government.

* It is the responsibility of any person or organization contemplating

* export to obtain such a license before exporting.

*

* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and

* distribute this software and its documentation for any purpose and

* without fee is hereby granted, provided that the above copyright

* notice appear in all copies and that both that copyright notice and

* this permission notice appear in supporting documentation, and that

* the name of M.I.T. not be used in advertising or publicity pertaining

* to distribution of the software without specific, written prior

* permission. Furthermore if you modify this software you must label

* your software as modified software and not distribute it in such a

* fashion that it might be confused with the original M.I.T. software.

* M.I.T. makes no representations about the suitability of

* this software for any purpose. It is provided "as is" without express

* or implied warranty.

*

*

* Implementation of PBKDF2 from RFC 2898.

* Not currently used; likely to be used when we get around to AES support.

*/

#include

#include "k5-int.h"

#include "hash_provider.h"

/* Not exported, for now. */

static krb5_error_code

krb5int_pbkdf2 (krb5_error_code (*prf)(krb5_keyblock *, krb5_data *,

krb5_data *),

size_t hlen, const krb5_data *pass, const krb5_data *salt,

unsigned long count, const krb5_data *output);

static int debug_hmac = 0;

static void printd (const char *descr, krb5_data *d) {

int i, j;

const int r = 16;

printf("%s:", descr);

for (i = 0; i < d->length; i += r) {

printf("\n %04x: ", i);

for (j = i; j < i + r && j < d->length; j++)

printf(" %02x", 0xff & d->data[j]);

for (; j < i + r; j++)

printf(" ");

printf(" ");

for (j = i; j < i + r && j < d->length; j++) {

int c = 0xff & d->data[j];

printf("%c", isprint(c) ? c : '.');

}

}

printf("\n");

}

static void printk(const char *descr, krb5_keyblock *k) {

krb5_data d;

d.data = (char *) k->contents;

d.length = k->length;

printd(descr, &d);

}

static krb5_error_code

F(char *output, char *u_tmp1, char *u_tmp2,

krb5_error_code (*prf)(krb5_keyblock *, krb5_data *, krb5_data *),

size_t hlen,

const krb5_data *pass, const krb5_data *salt,

unsigned long count, int i)

{

unsigned char ibytes[4];

size_t tlen;

int j, k;

krb5_keyblock pdata;

krb5_data sdata;

krb5_data out;

krb5_error_code err;

pdata.contents = pass->data;

pdata.length = pass->length;

#if 0

printf("F(i=%d, count=%lu, pass=%d:%s)\n", i, count,

pass->length, pass->data);

printk("F password", &pdata);

#endif

/* Compute U_1. */

ibytes[3] = i & 0xff;

ibytes[2] = (i >> 8) & 0xff;

ibytes[1] = (i >> 16) & 0xff;

ibytes[0] = (i >> 24) & 0xff;

tlen = salt->length;

memcpy(u_tmp2, salt->data, tlen);

memcpy(u_tmp2 + tlen, ibytes, 4);

tlen += 4;

sdata.data = u_tmp2;

sdata.length = tlen;

#if 0

printd("initial salt", &sdata);

#endif

out.data = u_tmp1;

out.length = hlen;

#if 0

printf("F: computing hmac #1 (U_1) with %s\n", pdata.contents);

#endif

err = (*prf)(&pdata, &sdata, &out);

if (err)

return err;

#if 0

printd("F: prf return value", &out);

#endif

memcpy(output, u_tmp1, hlen);

/* Compute U_2, .. U_c. */

sdata.length = hlen;

for (j = 2; j <= count; j++) {

#if 0

printf("F: computing hmac #%d (U_%d)\n", j, j);

#endif

memcpy(u_tmp2, u_tmp1, hlen);

err = (*prf)(&pdata, &sdata, &out);

if (err)

return err;

#if 0

printd("F: prf return value", &out);

#endif

/* And xor them together. */

for (k = 0; k < hlen; k++)

output[k] ^= u_tmp1[k];

#if 0

printf("F: xor result:\n");

for (k = 0; k < hlen; k++)

printf(" %02x", 0xff & output[k]);

printf("\n");

#endif

}

return 0;

}

static krb5_error_code

krb5int_pbkdf2 (krb5_error_code (*prf)(krb5_keyblock *, krb5_data *,

krb5_data *),

size_t hlen,

const krb5_data *pass, const krb5_data *salt,

unsigned long count, const krb5_data *output)

{

int l, r, i;

char *utmp1, *utmp2;

char utmp3[20];/* XXX length shouldn't be hardcoded! */

if (output->length == 0 || hlen == 0)

abort();

/* Step 1 & 2. */

if (output->length / hlen > 0xffffffff)

abort();

/* Step 2. */

l = (output->length + hlen - 1) / hlen;

r = output->length - (l - 1) * hlen;

utmp1 = /*output + dklen; */ malloc(hlen);

if (utmp1 == NULL)

return errno;

utmp2 = /*utmp1 + hlen; */ malloc(salt->length + 4 + hlen);

if (utmp2 == NULL) {

free(utmp1);

return errno;

}

/* Step 3. */

for (i = 1; i <= l; i++) {

#if 0

int j;

#endif

krb5_error_code err;

char *out;

if (i == l)

out = utmp3;

else

out = output->data + (i-1) * hlen;

err = F(out, utmp1, utmp2, prf, hlen, pass, salt, count, i);

if (err) {

free(utmp1);

free(utmp2);

return err;

}

if (i == l)

memcpy(output->data + (i-1) * hlen, utmp3,

output->length - (i-1) * hlen);

#if 0

printf("after F(%d), @%p:\n", i, output->data);

for (j = (i-1) * hlen; j < i * hlen; j++)

printf(" %02x", 0xff & output->data[j]);

printf ("\n");

#endif

}

free(utmp1);

free(utmp2);

return 0;

}

static krb5_error_code hmac1(const struct krb5_hash_provider *h,

krb5_keyblock *key, krb5_data *in, krb5_data *out)

{

char tmp[40];

size_t blocksize, hashsize;

krb5_error_code err;

krb5_keyblock k;

k = *key;

key = &k;

if (debug_hmac)

printk(" test key", key);

blocksize = h->blocksize;

hashsize = h->hashsize;

if (hashsize > sizeof(tmp))

abort();

if (key->length > blocksize) {

krb5_data d, d2;

d.data = (char *) key->contents;

d.length = key->length;

d2.data = tmp;

d2.length = hashsize;

err = h->hash (1, &d, &d2);

if (err)

return err;

key->length = d2.length;

key->contents = (krb5_octet *) d2.data;

if (debug_hmac)

printk(" pre-hashed key", key);

}

if (debug_hmac)

printd(" hmac input", in);

err = krb5_hmac(h, key, 1, in, out);

if (err == 0 && debug_hmac)

printd(" hmac output", out);

return err;

}

static krb5_error_code

foo(krb5_keyblock *pass, krb5_data *salt, krb5_data *out)

{

krb5_error_code err;

memset(out->data, 0, out->length);

err = hmac1 (&krb5int_hash_sha1, pass, salt, out);

return err;

}

krb5_error_code

krb5int_pbkdf2_hmac_sha1 (const krb5_data *out, unsigned long count,

const krb5_data *pass, const krb5_data *salt)

{

return krb5int_pbkdf2 (foo, 20, pass, salt, count, out);

}

SHA-512网上多

你可能感兴趣的:(pbkdf2,算法,C语言实现)