分享

网络安全编程与实践(第6章 OpenSSLEVP编程 代码)

 MikeDoc 2011-01-13

6.1.2

 

 

#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>

#define ITERATIVE_ROUND_FOR_KEY 6

#define CHARS_PER_LINE_BASE64 65
void print(const char* promptStr,unsigned char * data,int len)
{
 int i;
 printf("=================%s[长度=%d]============\n",promptStr,len);
 
 for(i=0;i<len;i++) printf("%02x",data[i]);
 printf("\n===========================================\n");
}

//base64 编码
void encode(
   unsigned char* outData,
   int * outlen,
   const unsigned char * data,
   int datalen
   )
{
 int tmp=0;
 EVP_ENCODE_CTX base64;
 EVP_EncodeInit(&base64);
 EVP_EncodeUpdate(
  &base64,
  outData,
  outlen,
  data,
  datalen
  );
 tmp=*outlen;
 
 EVP_EncodeFinal(
  &base64,
  outData+*outlen,
  outlen
  );
 *outlen+=tmp;
 outData[*outlen]=0;
 print(
  "base64 编码后:",
  outData,
  *outlen
  );
}

//base64 解码
bool decode(
   unsigned char * outData,
   int *outlen,
   const unsigned char * data,
   int datalen
   )
{
 int  i=0,tmp=0,currpos=0,lines=0;
 
 EVP_ENCODE_CTX base64;
 EVP_DecodeInit(&base64);
 for(;;)
 {
  currpos+=CHARS_PER_LINE_BASE64*lines++;
  i= EVP_DecodeUpdate(
   &base64,
   outData+tmp,
   outlen,
   data+currpos,
   datalen-currpos
   );
  if(i<0)
  {
   printf("解码错误!\n");
   return false;
  }
  tmp+=*outlen;
  if(i==0) break; 
 }
 
 EVP_DecodeFinal(&base64,outData+tmp,outlen);
 
 *outlen+=tmp;
 outData[*outlen]=0;
 print("base 64 解码后:",outData,*outlen);
 return true;
 
 
}

void main()
{
 
 OpenSSL_add_all_ciphers();
 OpenSSL_add_all_digests();
 
 
 //加密
 
 const EVP_CIPHER * type;
 type=EVP_des_ede3_cbc();
 printf("密钥长度=%d,向量长度=%d\n",type->key_len,type->iv_len);
 
 const char * password="renhl252";//用口令生成密钥
 printf("密码是:%s\n",password);
 
 unsigned char key[EVP_MAX_KEY_LENGTH];
 unsigned char iv[EVP_MAX_IV_LENGTH];
 
 EVP_BytesToKey(
  type,//密钥类型
  EVP_md5(),//摘要计算类型
  NULL,
  (const unsigned char *)password,
  (int)strlen(password),
  ITERATIVE_ROUND_FOR_KEY,//迭代轮数
  key,
  iv
  );
 
 EVP_CIPHER_CTX ctx;
 EVP_EncryptInit(&ctx,type,key,iv);
 
 char SimpleText[]="Let's pray for peace of our lovely world.";
 
 unsigned char out[512+8];
 int outl;
 
 int temp=(int)strlen(SimpleText);
 EVP_EncryptUpdate(
  &ctx,
  out,
  &outl,
  (const unsigned char *)SimpleText,
  (int)strlen(SimpleText)
  );
 temp=outl;
 EVP_EncryptFinal(&ctx,out+outl,&outl);
 outl+=temp;
 EVP_CIPHER_CTX_cleanup(&ctx);
 
 print("加密之后结果:",out,outl);
 
 unsigned char txtAfterBase64[sizeof(SimpleText)*3];
 
 //进行base64编码
 encode(
  txtAfterBase64,
  &temp,
  out,
  outl
  );
 
 memset(
  out,
  0,
  sizeof(out)
  );
 //解码
 decode(
  out,
  &outl,
  txtAfterBase64,
  temp
  );
 
 //解密
 unsigned char txAfterDecrypt[512];
 int txLenAfterDecrypt;
 EVP_DecryptInit(&ctx,type,key,iv);
 
 EVP_DecryptUpdate(
  &ctx,
  txAfterDecrypt,
  &txLenAfterDecrypt,
  out,
  outl
  );
 
 temp=txLenAfterDecrypt;
 
 EVP_DecryptFinal(&ctx,
  txAfterDecrypt+txLenAfterDecrypt,
  &txLenAfterDecrypt);
 
 txLenAfterDecrypt+=temp;
 
 EVP_CIPHER_CTX_cleanup(&ctx);
 txAfterDecrypt[txLenAfterDecrypt]=0;
 
 printf("解密之后结果(长度=%d):\n[%s]\n",txLenAfterDecrypt,txAfterDecrypt);
 printf("\n===========================================\n");
 
 printf("\nclick any key continue.");
 
  getchar();
 
}

 

6.2.2

#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>


void print(const char* promptStr,unsigned char * data,int len)
{
 int i;
 printf("=================%s[长度=%d]============\n",promptStr,len);
 
 for(i=0;i<len;i++) printf("%02x",data[i]);
 printf("\n===========================================\n");
}

//如果成功返回包装了RSA参数的EVP_PKEY,否则返回NULL
EVP_PKEY *getRSA()
{

EVP_PKEY *pkey=NULL;
RSA *rsa=RSA_generate_key(
        1024,
        RSA_3,
        NULL,
        NULL
        );
if(NULL==rsa)
{
printf("生成RSA密钥对失败!\n");
    return NULL;

}

//隐藏RSA密钥抵御定时攻击
RSA_blinding_on(rsa,NULL);
printf("\n成功生成RSA密钥对!\n");

pkey=EVP_PKEY_new();
if(NULL==pkey)
{
printf("EVP_PKEY_new failed\n");
RSA_free(rsa);
return NULL;
}
//将rsa对象赋给EVP_PKEY结构
EVP_PKEY_assign_RSA(pkey,rsa);

return pkey;
}

 

 


void main()
{
 
 OpenSSL_add_all_ciphers();
 
 EVP_PKEY *pkey=NULL;

 int len=-1;
 char plainText[]="[For test to public/private key encryption/decryption]";
 unsigned char  encData[512];
 unsigned char  decData[512];
 
 pkey=getRSA();
 
 if(pkey==NULL)
 {
 exit(-1);
 }

 len=EVP_PKEY_encrypt(
  encData,
  (unsigned char *)plainText,
  sizeof(plainText),
  pkey
  );
 if(len==-1)
 {
 printf("EVP_PKEY_encrypt加密失败\n");
 exit(-1);
 }
 print("加密后的数据",encData,len);

 len=EVP_PKEY_decrypt(
  decData,
  encData,
  len,
  pkey
  );
 if(len==-1)
 {
  printf("EVP_PKEY_decrypt解密失败\n");
  exit(-1);
 }
 print("解密后的数据",decData,len);

 printf("\n明文是:[长度=%d字节]:%s\n",len,decData);

 EVP_PKEY_free(pkey);

 printf("\nclick any key continue."); 
 getchar();
 
}

 

6.3.2

//哈希摘要算法

#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>

void main()
{

 

OpenSSL_add_all_digests();

//初始化上下文对象的初始函数
EVP_MD_CTX mdctx;
EVP_MD_CTX_init(&mdctx);

//初始化摘要算法
const char *digestName="sha1";//"md5";
const EVP_MD *md;
md=EVP_get_digestbyname(digestName);
if(!md)
{
printf("错误的摘要算法名称:%s\n",digestName);
exit(1);
}
EVP_DigestInit(&mdctx,md);

//要被计算的消息数组
 char msgs[][64]={
"It's just for test","Author:Jian Shen",
"HelloWord from openssl"
 };

//循环加入技术摘要的数据

for(int i=0;i<sizeof(msgs)/sizeof(msgs[0]);i++)
{
EVP_DigestUpdate(
     &mdctx,
     msgs[i],
     strlen(msgs[i])
     );
}

//结束摘要计算
unsigned int md_len;
unsigned char md_value[EVP_MAX_MD_SIZE];
EVP_DigestFinal(&mdctx,md_value,&md_len);
EVP_MD_CTX_cleanup(&mdctx);
printf("摘要值是:(类型=%s;长度=%d 字节):",digestName,md_len);

for(unsigned int j=0;j<md_len;j++)  printf("%02x",md_value[j]);
printf("\n");

 

 

}

 

6.4.2.txt

 

//哈希摘要算法

#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>


void print(const char* promptStr,unsigned char * data,int len)
{
 int i;
 printf("=================%s[长度=%d]============\n",promptStr,len);
 
 for(i=0;i<len;i++) printf("%02x",data[i]);
 printf("\n===========================================\n");
}

void main()
{

 

OpenSSL_add_all_digests();

HMAC_CTX mac_ctx;

//初始化摘要算法
const char *digestName="sha1";//"md5";
const EVP_MD *md;
md=EVP_get_digestbyname(digestName);
if(!md)
{
printf("错误的摘要算法名称:%s\n",digestName);
exit(1);
}

char key[]="simple_key";

HMAC_Init(&mac_ctx,key,sizeof(key),md);

unsigned char buffer[2048]="yasiuiasdasdooasdjidajiodjajiaiadjioioadidjjdjdjjdjjakkajajgewyeygedbdbbdbdb";
HMAC_Update(&mac_ctx,buffer,sizeof("yasiuiasdasdooasdjidajiodjajiaiadjioioadidjjdjdjjdjjakkajajgewyeygedbdbbdbdb"));

unsigned char mac_value[EVP_MAX_MD_SIZE];
unsigned int mac_len=0;
HMAC_Final(&mac_ctx,mac_value,&mac_len);

HMAC_cleanup(&mac_ctx);
printf("HMAC(%s,%s)\n",buffer,key);
print(NULL,mac_value,mac_len);

 

 


}

 

6.5.2.txt

 

#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/dsa.h>
#include <openssl/rsa.h>
#include <openssl/err.h>

void print(const char* promptStr,unsigned char * data,int len)
{
 int i;
 printf("=================%s[长度=%d]============\n",promptStr,len);
 
 for(i=0;i<len;i++) printf("%02x",data[i]);
 printf("\n===========================================\n");
}

//如果成功返回EVP_KEY,否则返回NULL
EVP_PKEY *getDSA()
{
 EVP_PKEY *pkey=NULL;

 DSA * dsa=DSA_generate_parameters(1024,NULL,0,NULL,NULL,NULL,NULL);
 if(NULL==dsa)
 {
 printf("生成DSA参数失败\n");
 return NULL;
 }
 printf("\nDSA参数成功产生!\n");

 int ret=0;
 ret=DSA_generate_key(dsa);
 if(ret==0)
 {
 printf("\nDSA_generate_key 调用失败\n");
 goto err;
 }
 printf("\nDSA密钥对生成成功\n");

 pkey=EVP_PKEY_new();

 if(NULL==pkey)
 {
 printf("\nEVP_PKEY_new 失败\n");
 goto err;
 }
 EVP_PKEY_assign_DSA(pkey,dsa);
 return pkey;
err:
 DSA_free(dsa);
 return NULL;
 }

void main()
{

OpenSSL_add_all_ciphers();

OpenSSL_add_all_digests();

EVP_MD_CTX mdctx;
EVP_MD_CTX_init(&mdctx);

const EVP_MD *md;
char mdName[]="dss1";
md=EVP_get_digestbyname(mdName);
if(!md)
{
printf("错误的摘要算法名称:%s\n",mdName);
exit(1);
}

EVP_SignInit(&mdctx,md);

//依次加入所要签名的数据
char msgs[][64]={
     "It's just for test.",
     "Author:Jian Shen",
     "Hello World from openssl"
};
int i;
for(i=0;i<sizeof(msgs)/sizeof(msgs[0]);i++)
{
EVP_SignUpdate(&mdctx,msgs[i],strlen(msgs[i]));
}

//计算签名;实际上该步先计算摘要值,然后对该值用私钥签名
unsigned char sig_value[1024];
unsigned int sig_len;

EVP_PKEY * pkey=NULL;
pkey=getDSA();
if(pkey==NULL)
{
exit(1);
}

i=EVP_SignFinal(
    &mdctx,
    sig_value,
    &sig_len,
    pkey
    );
if(i==0)
{
printf("计算签名失败");
exit(1);
}
EVP_MD_CTX_cleanup(&mdctx);
EVP_PKEY_free(pkey);
print("签名值是:",sig_value,sig_len);

}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多