当前位置:   article > 正文

国密sm2签名验签_sm2签名程序

sm2签名程序

生成私钥:

  1. #include <stdio.h>
  2. #include <openssl/ssl.h>
  3. #include <openssl/err.h>
  4. #include <openssl/pem.h>
  5. #include <openssl/conf.h>
  6. #include <openssl/x509v3.h>
  7. #include <openssl/bn.h>
  8. #include <openssl/evp.h>
  9. #include <openssl/asn1.h>
  10. #include <openssl/x509.h>
  11. #include <openssl/objects.h>
  12. #include <openssl/buffer.h>
  13. #ifndef OPENSSL_NO_ENGINE
  14. #include <openssl/engine.h>
  15. #endif
  16. int make_server_private_key()
  17. {
  18. OpenSSL_add_all_ciphers();
  19. OpenSSL_add_all_digests();
  20. ERR_load_crypto_strings();
  21. SSL_CTX *ctx = SSL_CTX_new (SSLv23_server_method ());
  22. SSL_CTX_set_options (ctx,
  23. SSL_OP_SINGLE_DH_USE |
  24. SSL_OP_SINGLE_ECDH_USE |
  25. SSL_OP_NO_SSLv2);
  26. EVP_PKEY *evk = EVP_PKEY_new();
  27. EC_KEY *ec_server = EC_KEY_new_by_curve_name (NID_sm2p256v1);
  28. if (! ec_server)
  29. printf("ecdh error!EC_KEY_new_by_curve_name\n");
  30. EC_KEY_generate_key(ec_server);
  31. BIO *bio_out = BIO_new_file("server_private.key", "w");
  32. PEM_write_bio_ECPrivateKey(bio_out, ec_server, NULL, NULL, 0, NULL, NULL);
  33. BIO_free(bio_out);
  34. EC_KEY_free(ec_server);
  35. EVP_PKEY_free(evk);
  36. return 0;
  37. }

生成证书

  1. int make_cert(char* name_C, char* name_S, char* name_L, char* name_O, char * name_OU, char* name_CN,
  2. char* PrivateKeyFileName, char* CertFileName )
  3. {
  4. X509 *x;
  5. EVP_PKEY *pk;
  6. X509_NAME *name = NULL;
  7. BIO * key = NULL;
  8. key = BIO_new(BIO_s_file());
  9. BIO_read_filename(key,PrivateKeyFileName);
  10. EC_KEY *ecdh = PEM_read_bio_ECPrivateKey(key, NULL, NULL, NULL);
  11. EVP_PKEY *evk = EVP_PKEY_new();
  12. EVP_PKEY_set1_EC_KEY(evk, ecdh);
  13. X509 *x509 = NULL;
  14. if (evk == NULL)
  15. {
  16. abort();
  17. return(0);
  18. }
  19. else
  20. pk = evk;
  21. if ((x = X509_new()) == NULL)
  22. return(0);
  23. X509_set_version(x, 2);
  24. int serial = 12345;
  25. ASN1_INTEGER_set(X509_get_serialNumber(x), serial);
  26. X509_gmtime_adj(X509_get_notBefore(x), 0);
  27. int days = 36500;
  28. X509_gmtime_adj(X509_get_notAfter(x), (long)60 * 60 * 24 * days);
  29. X509_set_pubkey(x, pk);
  30. name = X509_get_subject_name(x);
  31. X509_NAME_add_entry_by_txt(name, "C",
  32. MBSTRING_ASC, name_C, -1, -1, 0);
  33. X509_NAME_add_entry_by_txt(name, "S",
  34. MBSTRING_ASC, name_S, -1, -1, 0);
  35. X509_NAME_add_entry_by_txt(name, "L",
  36. MBSTRING_ASC, name_L, -1, -1, 0);
  37. X509_NAME_add_entry_by_txt(name, "O",
  38. MBSTRING_ASC, name_O, -1, -1, 0);
  39. X509_NAME_add_entry_by_txt(name, "OU",
  40. MBSTRING_ASC, name_OU, -1, -1, 0);
  41. X509_NAME_add_entry_by_txt(name, "CN",
  42. MBSTRING_ASC, name_CN, -1, -1, 0);
  43. X509_NAME *issuer_name=NULL;
  44. if (!issuer_name)
  45. X509_set_issuer_name(x, name);
  46. else
  47. X509_set_issuer_name(x, issuer_name);
  48. int n=X509_sign(x, evk, EVP_sm3());
  49. x509 = x;
  50. evk = pk;
  51. BIO *bio_x = BIO_new_file(CertFileName, "w");
  52. PEM_write_bio_X509(bio_x, x509);
  53. printf("n=%d\n",n);
  54. BIO_free(bio_x);
  55. EVP_PKEY_free(evk);
  56. EC_KEY_free(ecdh);
  57. X509_free(x509);
  58. return(1);
  59. }

以下代码有可能不符合国标

签名

  1. int signature(char *msg)
  2. {
  3. int ret = 0;
  4. unsigned int slen=256;
  5. unsigned char sig[256];
  6. BIO * key = NULL;
  7. key = BIO_new(BIO_s_file());
  8. BIO_read_filename(key,"server_private.key");
  9. EC_KEY *ecdh = PEM_read_bio_ECPrivateKey(key, NULL, NULL, NULL);
  10. printf("sig len:%d\n", ECDSA_size(ecdh));
  11. if (!SM2_sign(0,msg, strlen(msg), sig,&slen,ecdh))
  12. {
  13. return 0;
  14. }
  15. FILE *fp = fopen("server_16.sig", "wb");
  16. for(int i=0; i < slen; i++)
  17. {
  18. fwrite(((unsigned char*)(sig+i)), 1, 1, fp);
  19. }
  20. fclose(fp);
  21. printf("slen:%d\n", slen);
  22. for(int i=0; i < slen; i++)
  23. {
  24. printf("%02x ", *((unsigned char*)(sig+i)));
  25. }
  26. printf("\n");
  27. /* 成功 */
  28. ret = 1;
  29. /* 清理 */
  30. return ret;
  31. }

验签

  1. int verify_sig(void *sig, char *msg, size_t slen)
  2. {
  3. int nRet;
  4. ECDSA_SIG *s;
  5. const unsigned char *p = sig;
  6. unsigned char *der = NULL;
  7. int derlen = -1;
  8. int ret = -1;
  9. FILE *fp = fopen("server_cert.pem", "r");
  10. X509 *cert = PEM_read_X509(fp, NULL, NULL, NULL);
  11. //FILE *fp = fopen("server_cert.der", "r");
  12. //X509 *cert = d2i_X509_fp(fp, NULL);
  13. EVP_PKEY *evk = X509_get_pubkey(cert);
  14. EC_KEY *ec_key=EVP_PKEY_get0_EC_KEY(evk);
  15. printf("\nslen:%ld\n", slen);
  16. for(int i=0; i < slen; i++)
  17. {
  18. printf("%02x ", *((unsigned char*)(sig+i)));
  19. }
  20. printf("\n");
  21. nRet = SM2_verify(0,msg, strlen(msg), sig, slen,ec_key);
  22. return nRet == 1 ? 1 : 0;
  23. }

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

闽ICP备14008679号