⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pbkdf2.c

📁 Linux下的飞鸽传书
💻 C
字号:
/* * Following codes are derived from  * ``Secure Programming Cookbook for C and C++''. * URL:http://www.oreilly.com/catalog/secureprgckbk/  *     http://www.secureprogramming.com/ *  * Licensing Information can be obtain from following URL: * *  http://www.secureprogramming.com/?action=license * * Copyright  2003 by John Viega and Matt Messier. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met:  * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the *  documentation and/or other materials provided with the distribution. * * 3. Neither the name of the developer of this software nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. *  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */#include <stdio.h>#include <string.h>#include <unistd.h>#include <stdlib.h>#include <fcntl.h>#include <errno.h>#include <sys/types.h>#include <netinet/in.h>#include <arpa/inet.h>#include <openssl/evp.h>#include <openssl/hmac.h>#include "common.h"/*  pkcs5  */static voidpkcs5_initial_prf(unsigned char *p,		  size_t plen,		  unsigned char *salt,		  size_t saltlen,		  size_t i,		  unsigned char *out,		  size_t *outlen){  size_t swapped_i;  HMAC_CTX ctx;  HMAC_CTX_init(&ctx);  HMAC_Init(&ctx,p,plen,EVP_sha1());  HMAC_Update(&ctx,salt,saltlen);  swapped_i=htonl(i);  HMAC_Update(&ctx,(unsigned char *)&swapped_i,sizeof(swapped_i));  HMAC_Final(&ctx,out,(unsigned int *)outlen);  HMAC_CTX_cleanup(&ctx);}static voidpkcs5_subsequent_prf(unsigned char *p,		     size_t plen,		     unsigned char *v,		     size_t vlen,		     unsigned char *o,		     size_t *olen){  HMAC_CTX ctx;  HMAC_CTX_init(&ctx);  HMAC_Init(&ctx,p,plen,EVP_sha1());  HMAC_Update(&ctx,v,vlen);  HMAC_Final(&ctx,o,(unsigned int *)olen);  HMAC_CTX_cleanup(&ctx);}static voidpkcs5_F(unsigned char *p,	size_t plen,	unsigned char *salt,	size_t saltlen,	size_t ic,	size_t bix,	unsigned char *out){  size_t i,j,outlen;  unsigned char ulast[PBKDF2_PRF_OUT_LEN];    memset(out,0,PBKDF2_PRF_OUT_LEN);  pkcs5_initial_prf(p,plen,salt,saltlen,bix,ulast,&outlen);  for(i=1;i<=ic;++i){    for(j=0;j<PBKDF2_PRF_OUT_LEN;j++)      out[j] ^= ulast[j];    pkcs5_subsequent_prf(p,plen,ulast,PBKDF2_PRF_OUT_LEN,ulast,&outlen);  }  for(j=0;j<PBKDF2_PRF_OUT_LEN;j++)    out[j] ^= ulast[j];}static void spc_pbkdf2(unsigned char *pw, size_t pwlen, char *salt, uint64_t saltlen, uint32_t ic, unsigned char *dk,uint64_t dklen){  uint32_t i,l,r;  unsigned char final[PBKDF2_PRF_OUT_LEN]={0,};    if (dklen > (((unsigned long long)1)<<32 -1) * PBKDF2_PRF_OUT_LEN){    abort();  }  l=dklen / PBKDF2_PRF_OUT_LEN;  r=dklen % PBKDF2_PRF_OUT_LEN;  for(i=1;i<=l;++i)    pkcs5_F(pw,pwlen,salt,saltlen,ic,i,dk + (i-1) * PBKDF2_PRF_OUT_LEN);  if (r) {    pkcs5_F(pw,pwlen,salt,saltlen,ic,i,final);    for(l=0;l<r;++l)      *(dk + (i-1) * PBKDF2_PRF_OUT_LEN + l) = final[l];  }}intpbkdf2_encrypt(const char *key, const char *salt,char **enc_pass) {  int rc;  int i;  size_t num_len;  unsigned char *raw_salt=NULL;  unsigned char *base64_salt=NULL;  unsigned char *base64_out=NULL;  unsigned int iterations,tmp_num;  size_t key_len;  size_t salt_len,encoded_salt_len;  size_t result_len;  char *output=NULL;  char *ret_str;  char *salt_end=NULL,*endptr;  unsigned long tmp_ulong;  if ( (!key) || (!enc_pass) )    return -EINVAL;  /*   * Saltとくり返し回数を設定   */  if (!salt) {    raw_salt=g_malloc(PBKDF2_SALT_LEN);    if (!raw_salt)      return -ENOMEM;    rc=generate_rand(raw_salt, PBKDF2_SALT_LEN);    if (rc)      goto free_raw_salt;    rc=base64_encode(raw_salt, PBKDF2_SALT_LEN,(gchar **)&base64_salt);    if (rc)      goto free_raw_salt;    iterations=PBKDF2_ITER_CNT;    salt_len=PBKDF2_SALT_LEN;  }else{    if (strncmp(salt,PBKDF2_PREFIX,PBKDF2_PREFIX_LEN))      return -EINVAL;    salt_end = strchr(salt + PBKDF2_PREFIX_LEN,'$');    if (!salt_end)      return -EINVAL;    encoded_salt_len=salt_end - (salt + PBKDF2_PREFIX_LEN) + 1;    base64_salt=g_malloc(encoded_salt_len+1);    if (!base64_salt)      return -ENOMEM;    memcpy(base64_salt,salt + PBKDF2_PREFIX_LEN,encoded_salt_len);    base64_salt[encoded_salt_len-1]='\0';    dbg_out("base64 salt:%s\n",base64_salt);    errno=0;    endptr=NULL;    tmp_ulong=strtoul(salt_end + 1,&endptr,10);    if ( (tmp_ulong == ULONG_MAX && errno == ERANGE) ||	 (tmp_ulong > UINT_MAX)                      ||	 (!endptr)                                   ||	 (*endptr != '$') ) {      g_free(base64_salt);      return -EINVAL;    }    iterations=(unsigned long)tmp_ulong;    rc=base64_decode(base64_salt,&salt_len,(gchar **)&raw_salt);    if (rc) {      g_free(base64_salt);      return rc;    }  }  output=g_malloc(PBKDF2_KEY_LEN);  if (!output)    goto free_base64_encoded_salt;  key_len=strlen(key);  spc_pbkdf2((unsigned char *)key,key_len,raw_salt,salt_len,iterations,output,PBKDF2_KEY_LEN);  rc=base64_encode(key,key_len+1,(gchar **)&base64_out);  if (rc)    goto free_output;  for(num_len=1,tmp_num=iterations;tmp_num;++num_len,tmp_num/=10);  result_len=strlen(base64_out)+strlen(base64_salt)+num_len+PBKDF2_FORMAT_ADDED_LEN+1;  dbg_out("result_len:%d\n",result_len);  ret_str=g_malloc(result_len);  rc=-ENOMEM;  if (!ret_str)    goto free_base64_encoded_out;  snprintf(ret_str,result_len,PBKDF2_FORMAT,base64_salt,iterations,base64_out);  ret_str[result_len-1]='\0';  dbg_out("ret_str:%s\n",ret_str);  *enc_pass=ret_str;    rc=0; free_base64_encoded_out:  if (base64_out)    g_free(base64_out); free_output:  if (output)    g_free(output); free_base64_encoded_salt:  if (base64_salt)    g_free(base64_salt); free_raw_salt:  if (raw_salt)    g_free(raw_salt);  return rc;}intpbkdf2_verify(const char *plain_passwd,const char *crypt_passwd){  int rc;  int match=0;  char *pbkdf2_result;  if ( (!plain_passwd) || (!crypt_passwd) )    return -EINVAL;  rc=pbkdf2_encrypt(plain_passwd,crypt_passwd,&pbkdf2_result);  if (rc)    goto error_out;  match=strcmp(pbkdf2_result,crypt_passwd); error_out:  g_free(pbkdf2_result);  dbg_out("comp:%d\n",match);  return match;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -