openssl evp

缺乏、安全感 2022-05-23 04:09 327阅读 0赞

openssl evp 对称加密(AES_ecb,ccb)

evp.h 封装了openssl常用密码学工具,以下主要说对称加密的接口

  1. 如下使用 aes_256_ecb 模式的加密解密测试代码

复制代码

  1. unsigned char key[32] = {
  2. 1};
  3. unsigned char iv[16] = {
  4. 0};
  5. unsigned char *inStr = "this is test string";
  6. int inLen = strlen(inStr);
  7. int encLen = 0;
  8. int outlen = 0;
  9. unsigned char encData[1024];
  10. printf("source: %s\n",inStr);
  11. //加密
  12. EVP_CIPHER_CTX *ctx;
  13. ctx = EVP_CIPHER_CTX_new();
  14. EVP_CipherInit_ex(ctx, EVP_aes_256_ecb(), NULL, key, iv, 1);
  15. EVP_CipherUpdate(ctx, encData, &outlen, inStr, inLen);
  16. encLen = outlen;
  17. EVP_CipherFinal(ctx, encData+outlen, &outlen);
  18. encLen += outlen;
  19. EVP_CIPHER_CTX_free(ctx);
  20. //解密
  21. int decLen = 0;
  22. outlen = 0;
  23. unsigned char decData[1024];
  24. EVP_CIPHER_CTX *ctx2;
  25. ctx2 = EVP_CIPHER_CTX_new();
  26. EVP_CipherInit_ex(ctx2, EVP_aes_256_ecb(), NULL, key, iv, 0);
  27. EVP_CipherUpdate(ctx2, decData, &outlen, encData, encLen);
  28. decLen = outlen;
  29. EVP_CipherFinal(ctx2, decData+outlen, &outlen);
  30. decLen += outlen;
  31. EVP_CIPHER_CTX_free(ctx2);
  32. decData[decLen] = '\0';
  33. printf("decrypt: %s\n",decData);

复制代码

如上这种init,update,final的调用方式和之前 提供的哈希接口调用方式差不多

大致流程

EVP_CipherInit_ex 初始化加密使用的key,iv,算法模式,最后 一个参数,1表示加密,0表示解密

EVP_CipherUpdate 加密解密处理

EVP_CipherFinal 获取结果

  1. 由上测试代码中 EVP_CipherInit_ex(ctx, EVP_aes_256_ecb(), NULL, key, iv, 1); 使用的算法模式为 EVP_aes_256_ecb()

    根据接口 evp.h可知其他的对称加密算法有如下

复制代码

  1. const EVP_CIPHER *EVP_des_ecb(void);
  2. const EVP_CIPHER *EVP_des_ede(void);
  3. const EVP_CIPHER *EVP_des_ede3(void);
  4. ...
  5. const EVP_CIPHER *EVP_idea_ecb(void);
  6. const EVP_CIPHER *EVP_idea_cfb64(void);
  7. const EVP_CIPHER *EVP_idea_ofb(void);
  8. .....
  9. const EVP_CIPHER *EVP_bf_cbc(void);
  10. const EVP_CIPHER *EVP_bf_cfb64(void);
  11. .....
  12. const EVP_CIPHER *EVP_cast5_ecb(void);
  13. const EVP_CIPHER *EVP_cast5_cbc(void);
  14. .....
  15. const EVP_CIPHER *EVP_aes_128_ecb(void);
  16. const EVP_CIPHER *EVP_aes_128_cbc(void);
  17. const EVP_CIPHER *EVP_aes_128_cfb1(void);
  18. ......
  19. const EVP_CIPHER *EVP_aes_256_ecb(void);
  20. const EVP_CIPHER *EVP_aes_256_cbc(void);
  21. const EVP_CIPHER *EVP_aes_256_cfb1(void);
  22. ....
  23. const EVP_CIPHER *EVP_camellia_128_cfb1(void);
  24. const EVP_CIPHER *EVP_camellia_128_cfb8(void);
  25. const EVP_CIPHER *EVP_camellia_128_cfb128(void);
  26. ......
  27. //以上省略表示还有很多,这里只是列出部分

复制代码

选取相应的算法对应修改上面的测试代码即可,实现对称加密体系中其他算法的加密解密

  1. EVP中对称加密的主要接口有

复制代码

  1. __owur int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
  2. const unsigned char *key, const unsigned char *iv);
  3. /*__owur*/ int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,
  4. const EVP_CIPHER *cipher, ENGINE *impl,
  5. const unsigned char *key,
  6. const unsigned char *iv);
  7. /*__owur*/ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
  8. int *outl, const unsigned char *in, int inl);
  9. /*__owur*/ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out,
  10. int *outl);
  11. /*__owur*/ int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out,
  12. int *outl);
  13. __owur int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
  14. const unsigned char *key, const unsigned char *iv);
  15. /*__owur*/ int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx,
  16. const EVP_CIPHER *cipher, ENGINE *impl,
  17. const unsigned char *key,
  18. const unsigned char *iv);
  19. /*__owur*/ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
  20. int *outl, const unsigned char *in, int inl);
  21. __owur int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm,
  22. int *outl);
  23. /*__owur*/ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm,
  24. int *outl);
  25. __owur int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
  26. const unsigned char *key, const unsigned char *iv,
  27. int enc);
  28. /*__owur*/ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx,
  29. const EVP_CIPHER *cipher, ENGINE *impl,
  30. const unsigned char *key,
  31. const unsigned char *iv, int enc);
  32. __owur int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
  33. int *outl, const unsigned char *in, int inl);
  34. __owur int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm,
  35. int *outl);
  36. __owur int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm,
  37. int *outl);

复制代码

  1. 上面的例子之中,我使用的是EVP_Cipher相关api处理的对称加密

    如下,我们还可以直接使用上面的 EVP_Encrypt,EVP_Decrypt 接口来处理加密解密

    封装加密解密

复制代码

  1. //加密
  2. int kk_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key,
  3. unsigned char *iv, unsigned char *ciphertext)
  4. {
  5. EVP_CIPHER_CTX *ctx;
  6. int len;
  7. int ciphertext_len;
  8. ctx = EVP_CIPHER_CTX_new();
  9. EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv);
  10. EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len);
  11. ciphertext_len = len;
  12. EVP_EncryptFinal_ex(ctx, ciphertext + len, &len);
  13. ciphertext_len += len;
  14. EVP_CIPHER_CTX_free(ctx);
  15. return ciphertext_len;
  16. }
  17. //解密
  18. int kk_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key,
  19. unsigned char *iv, unsigned char *plaintext)
  20. {
  21. EVP_CIPHER_CTX *ctx;
  22. int len;
  23. int plaintext_len;
  24. ctx = EVP_CIPHER_CTX_new();
  25. EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv);
  26. EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len);
  27. plaintext_len = len;
  28. EVP_DecryptFinal_ex(ctx, plaintext + len, &len);
  29. plaintext_len += len;
  30. EVP_CIPHER_CTX_free(ctx);
  31. return plaintext_len;
  32. }

复制代码

调用测试:

复制代码

  1. unsigned char key[32] = {
  2. 8};
  3. unsigned char iv[16] = {
  4. 6};
  5. unsigned char *plaintext = (unsigned char *)"This is Test Plain Data,This is Test Plain Data.";
  6. unsigned char ciphertext[128];
  7. unsigned char decryptedtext[128];
  8. int decryptedtext_len, ciphertext_len;
  9. printf("source is: \n%s\n",plaintext);
  10. //加密
  11. ciphertext_len = kk_encrypt (plaintext, strlen ((char *)plaintext), key, iv,
  12. ciphertext);
  13. //解密
  14. decryptedtext_len = kk_decrypt(ciphertext, ciphertext_len, key, iv,
  15. decryptedtext);
  16. decryptedtext[decryptedtext_len] = '\0';
  17. printf("Decrypted text is:\n");
  18. printf("%s\n", decryptedtext);

复制代码

和上面第一个例子的流程差不多,修改其中的对称体系使用的算法即可实现其他算法处理

  1. 如果不使用EVP提供的接口,当然还可以直接使用 aes.h 提供的接口

    主要接口有

复制代码

  1. /* This should be a hidden type, but EVP requires that the size be known */
  2. struct aes_key_st {
  3. # ifdef AES_LONG
  4. unsigned long rd_key[4 * (AES_MAXNR + 1)];
  5. # else
  6. unsigned int rd_key[4 * (AES_MAXNR + 1)];
  7. # endif
  8. int rounds;
  9. };
  10. typedef struct aes_key_st AES_KEY;
  11. const char *AES_options(void);
  12. int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
  13. AES_KEY *key);
  14. int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
  15. AES_KEY *key);
  16. void AES_encrypt(const unsigned char *in, unsigned char *out,
  17. const AES_KEY *key);
  18. void AES_decrypt(const unsigned char *in, unsigned char *out,
  19. const AES_KEY *key);
  20. void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
  21. const AES_KEY *key, const int enc);
  22. void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
  23. size_t length, const AES_KEY *key,
  24. unsigned char *ivec, const int enc);
  25. void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
  26. size_t length, const AES_KEY *key,
  27. unsigned char *ivec, int *num, const int enc);
  28. void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
  29. size_t length, const AES_KEY *key,
  30. unsigned char *ivec, int *num, const int enc);
  31. void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
  32. size_t length, const AES_KEY *key,
  33. unsigned char *ivec, int *num, const int enc);
  34. void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
  35. size_t length, const AES_KEY *key,
  36. unsigned char *ivec, int *num);
  37. /* NB: the IV is _two_ blocks long */
  38. void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
  39. size_t length, const AES_KEY *key,
  40. unsigned char *ivec, const int enc);
  41. /* NB: the IV is _four_ blocks long */
  42. void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
  43. size_t length, const AES_KEY *key,
  44. const AES_KEY *key2, const unsigned char *ivec,
  45. const int enc);
  46. int AES_wrap_key(AES_KEY *key, const unsigned char *iv,
  47. unsigned char *out,
  48. const unsigned char *in, unsigned int inlen);
  49. int AES_unwrap_key(AES_KEY *key, const unsigned char *iv,
  50. unsigned char *out,
  51. const unsigned char *in, unsigned int inlen);

复制代码

测试接口AES_encrypt,AES_decrypt

复制代码

  1. //测试1
  2. void kk_aes_encrypt(char *inData,char *key,char *outData)
  3. {
  4. AES_KEY encKey;
  5. AES_set_encrypt_key(key, 128, &encKey);
  6. int inLen = strlen(inData);
  7. int encLen = 0;
  8. //分组加密
  9. while (encLen <inLen) {
  10. AES_encrypt(inData, outData, &encKey);
  11. inData += AES_BLOCK_SIZE;
  12. outData+=AES_BLOCK_SIZE;
  13. encLen +=AES_BLOCK_SIZE;
  14. }
  15. }
  16. void kk_aes_decrypt(char *inData,char *key,char *outData)
  17. {
  18. AES_KEY decKey;
  19. AES_set_decrypt_key(key, 128, &decKey);
  20. int inLen = strlen(inData);
  21. int decLen = 0;
  22. //分组处理
  23. while (decLen < inLen) {
  24. AES_decrypt(inData, outData, &decKey);
  25. inData += AES_BLOCK_SIZE;
  26. outData+=AES_BLOCK_SIZE;
  27. decLen +=AES_BLOCK_SIZE;
  28. }
  29. }
  30. //测试
  31. void testSIMPLEAES()
  32. {
  33. char *key = "this key";
  34. char *ins = "test str dat,test str dat,test str dat,test str dat,QQQS";
  35. printf("src:%s\n",ins);
  36. char *encDT = malloc(strlen(ins));
  37. kk_aes_encrypt(ins, key, encDT);
  38. char *decDT = malloc(strlen(encDT));
  39. kk_aes_decrypt(encDT, key, decDT);
  40. printf("dec:%s\n",decDT);
  41. }

复制代码

测试AES_cbc_encrypt接口

复制代码

  1. AES_KEY encKEy;
  2. unsigned char *uk = "uk123";
  3. char encIV[AES_BLOCK_SIZE] = {
  4. 0};
  5. AES_set_encrypt_key(uk, 128, &encKEy);
  6. char *inStr = "This wiki is intended as a place for collecting, organizing, and refining useful information about OpenSSL that is currently strewn among multiple locations and formats.";
  7. char *encData = malloc(1024);
  8. AES_cbc_encrypt(inStr, encData, strlen(inStr), &encKEy, encIV, AES_ENCRYPT);
  9. printf("src:%s\n",inStr);
  10. AES_KEY decKey;
  11. AES_set_decrypt_key(uk, 128, &decKey);
  12. char decIV[AES_BLOCK_SIZE] = {
  13. 0};
  14. char *decData = malloc(1024);
  15. AES_cbc_encrypt(encData,decData, strlen(encData), &decKey, decIV, AES_DECRYPT);
  16. decData[strlen(inStr)] = '\0';
  17. printf("dec:%s\n",decData);
  18. if (strcmp(inStr, decData)==0) {
  19. printf("PASS\n");
  20. }

发表评论

表情:
评论列表 (有 0 条评论,327人围观)

还没有评论,来说两句吧...

相关阅读

    相关 openssl

    > `openssl`是一个加解密相关的库,这个库在计算机领域得到了广泛的应用。 1.操作系统中安装`openssl` > 安装`openssl`扩展之前,你的操作系统

    相关 OpenSSL简介

    OpenSSL简介 目录 目录 第一章 前言 第二章 证书 第三章 加密算法 第四章 协议 第五章 入门 第六章 指令 verify 第七章 指令as

    相关 openssl 简介

    OpenSSL是一个基于密码学的安全开发包,OpenSSL提供的功能相当强大和全面,囊括了主要的密码算法、常用的密钥和证书封装管理功能以及SSL协议,并提供了丰富的应用