当前位置:   article > 正文

Compute SM2 encryption and decryption by invoking EVP interface in OpenSSL 1.1.1_sm2l.cc下载吧

sm2l.cc下载吧

    How to compute SM2 signature and verify it is introduced in the previous article. In this post a demo of performing SM2 encryption and decryption by invoking EVP interface in OpenSSL 1.1.1 is provided:

  1. /**************************************************
  2. * File name: EVP_sm2_encrypt_and_decrypt.c
  3. * Author: HAN Wei
  4. * Author's blog: https://blog.csdn.net/henter/
  5. * Date: May 1st, 2020
  6. * Description: demonstrate how to compute SM2 encryption
  7. and decryption by invoking EVP interface
  8. in OpenSSL 1.1.1
  9. **************************************************/
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include "openssl/ec.h"
  14. #include "openssl/evp.h"
  15. /**************************************************
  16. * Main function return value:
  17. 0: main function executes successfully
  18. -1: an error occurs
  19. **************************************************/
  20. int main(void)
  21. {
  22. int ret = -1, i;
  23. EVP_PKEY_CTX *pctx = NULL, *ectx = NULL;
  24. EVP_PKEY *pkey = NULL;
  25. unsigned char message[16] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
  26. 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF };
  27. size_t message_len = sizeof(message);
  28. unsigned char *ciphertext = NULL, *plaintext = NULL;
  29. size_t ciphertext_len, plaintext_len;
  30. EC_KEY *key_pair = NULL;
  31. const BIGNUM *priv_key = NULL;
  32. char *priv_key_str = NULL;
  33. const EC_GROUP *group = NULL;
  34. const EC_POINT *pub_key = NULL;
  35. BN_CTX *ctx = NULL;
  36. BIGNUM *x_coordinate = NULL, *y_coordinate = NULL;
  37. char *x_coordinate_str = NULL, *y_coordinate_str = NULL;
  38. /* create SM2 Ellipse Curve parameters and key pair */
  39. if ( !(pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) )
  40. {
  41. goto clean_up;
  42. }
  43. if ( (EVP_PKEY_paramgen_init(pctx)) != 1 )
  44. {
  45. goto clean_up;
  46. }
  47. if ( (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_sm2)) <= 0 )
  48. {
  49. goto clean_up;
  50. }
  51. if ( (EVP_PKEY_keygen_init(pctx)) != 1 )
  52. {
  53. goto clean_up;
  54. }
  55. if ( (EVP_PKEY_keygen(pctx, &pkey)) != 1 )
  56. {
  57. goto clean_up;
  58. }
  59. /* print SM2 key pair */
  60. if ( !(key_pair = EVP_PKEY_get0_EC_KEY(pkey)) )
  61. {
  62. goto clean_up;
  63. }
  64. if ( !(priv_key = EC_KEY_get0_private_key(key_pair)) )
  65. {
  66. goto clean_up;
  67. }
  68. if ( !(priv_key_str = BN_bn2hex(priv_key)) )
  69. {
  70. goto clean_up;
  71. }
  72. printf("SM2 private key (in hex form):\n");
  73. printf("%s\n\n", priv_key_str);
  74. if ( !(pub_key = EC_KEY_get0_public_key(key_pair)) )
  75. {
  76. goto clean_up;
  77. }
  78. if ( !(group = EC_KEY_get0_group(key_pair)) )
  79. {
  80. goto clean_up;
  81. }
  82. if ( !(ctx = BN_CTX_new()) )
  83. {
  84. goto clean_up;
  85. }
  86. BN_CTX_start(ctx);
  87. x_coordinate = BN_CTX_get(ctx);
  88. y_coordinate = BN_CTX_get(ctx);
  89. if ( !(y_coordinate) )
  90. {
  91. goto clean_up;
  92. }
  93. if ( !(EC_POINT_get_affine_coordinates(group, pub_key, x_coordinate, y_coordinate, ctx)) )
  94. {
  95. goto clean_up;
  96. }
  97. if ( !(x_coordinate_str = BN_bn2hex(x_coordinate)) )
  98. {
  99. goto clean_up;
  100. }
  101. printf("x coordinate in SM2 public key (in hex form):\n");
  102. printf("%s\n\n", x_coordinate_str);
  103. if ( !(y_coordinate_str = BN_bn2hex(y_coordinate)) )
  104. {
  105. goto clean_up;
  106. }
  107. printf("y coordinate in SM2 public key (in hex form):\n");
  108. printf("%s\n\n", y_coordinate_str);
  109. /* compute SM2 encryption */
  110. if ( (EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2)) != 1 )
  111. {
  112. goto clean_up;
  113. }
  114. if ( !(ectx = EVP_PKEY_CTX_new(pkey, NULL)) )
  115. {
  116. goto clean_up;
  117. }
  118. if ( (EVP_PKEY_encrypt_init(ectx)) != 1 )
  119. {
  120. goto clean_up;
  121. }
  122. if ( (EVP_PKEY_encrypt(ectx, NULL, &ciphertext_len, message, message_len)) != 1 )
  123. {
  124. goto clean_up;
  125. }
  126. if ( !(ciphertext = (unsigned char *)malloc(ciphertext_len)) )
  127. {
  128. goto clean_up;
  129. }
  130. if ( (EVP_PKEY_encrypt(ectx, ciphertext, &ciphertext_len, message, message_len)) != 1 )
  131. {
  132. goto clean_up;
  133. }
  134. printf("Message length: %d bytes.\n", message_len);
  135. printf("Message:\n");
  136. for (i = 0; i < (int)message_len; i++)
  137. {
  138. printf("0x%x ", message[i]);
  139. }
  140. printf("\n\n");
  141. printf("Ciphertext length: %d bytes.\n", ciphertext_len);
  142. printf("Ciphertext (ASN.1 encode):\n");
  143. for (i = 0; i < (int)ciphertext_len; i++)
  144. {
  145. printf("0x%x ", ciphertext[i]);
  146. }
  147. printf("\n\n");
  148. /* compute SM2 decryption */
  149. if ( (EVP_PKEY_decrypt_init(ectx)) != 1 )
  150. {
  151. goto clean_up;
  152. }
  153. if ( (EVP_PKEY_decrypt(ectx, NULL, &plaintext_len, ciphertext, ciphertext_len)) != 1 )
  154. {
  155. goto clean_up;
  156. }
  157. if ( !(plaintext = (unsigned char *)malloc(plaintext_len)) )
  158. {
  159. goto clean_up;
  160. }
  161. if ( (EVP_PKEY_decrypt(ectx, plaintext, &plaintext_len, ciphertext, ciphertext_len)) != 1 )
  162. {
  163. goto clean_up;
  164. }
  165. printf("Decrypted plaintext length: %d bytes.\n", plaintext_len);
  166. printf("Decrypted plaintext:\n");
  167. for (i = 0; i < (int)plaintext_len; i++)
  168. {
  169. printf("0x%x ", plaintext[i]);
  170. }
  171. printf("\n\n");
  172. if ( plaintext_len != message_len )
  173. {
  174. printf("Decrypted data length error!\n");
  175. goto clean_up;
  176. }
  177. if ( memcmp(plaintext, message, message_len) )
  178. {
  179. printf("Decrypt data failed!\n");
  180. goto clean_up;
  181. }
  182. else
  183. {
  184. printf("Encrypt and decrypt data succeeded!\n");
  185. }
  186. ret = 0;
  187. clean_up:
  188. if (pctx)
  189. {
  190. EVP_PKEY_CTX_free(pctx);
  191. }
  192. if (pkey)
  193. {
  194. EVP_PKEY_free(pkey);
  195. }
  196. if (priv_key_str)
  197. {
  198. OPENSSL_free(priv_key_str);
  199. }
  200. if (ctx)
  201. {
  202. BN_CTX_end(ctx);
  203. BN_CTX_free(ctx);
  204. }
  205. if (x_coordinate_str)
  206. {
  207. OPENSSL_free(x_coordinate_str);
  208. }
  209. if (y_coordinate_str)
  210. {
  211. OPENSSL_free(y_coordinate_str);
  212. }
  213. if (ectx)
  214. {
  215. EVP_PKEY_CTX_free(ectx);
  216. }
  217. if (ciphertext)
  218. {
  219. free(ciphertext);
  220. }
  221. if (plaintext)
  222. {
  223. free(plaintext);
  224. }
  225. #if defined(_WIN32) || defined(_WIN64)
  226. system("pause");
  227. #endif
  228. return ret;
  229. }

    The result is as below:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/998307
推荐阅读
相关标签
  

闽ICP备14008679号