当前位置:   article > 正文

OpenSSL/GMSSL EVP接口说明——3.5 加密解密_evp_pkey_ctx_set_ec_sign_type( pkctx, nid_sm_schem

evp_pkey_ctx_set_ec_sign_type( pkctx, nid_sm_scheme)

3.5 加密解密

加密解密流程

假设EVP_PKEY *pkey已经生成完毕。

表3.3 加密解密步骤

加密(多步式)

解密(多步式)

1

pkctx = EVP_PKEY_CTX_new(

pkey, NULL))

pkctx = EVP_PKEY_CTX_new(

pkey, NULL))

2

EVP_PKEY_encrypt_init(pkctx)

EVP_PKEY_decrypt_init(pkctx)

3

EVP_PKEY_CTX_set_ec_enc_type(

pkctx, NID_sm_scheme)

EVP_PKEY_CTX_set_ec_enc_type(

pkctx, NID_sm_scheme)

4

EVP_PKEY_encrypt(

pkctx, ct, &clen, msg, mlen)

EVP_PKEY_decrypt(

pkctx, mbuf, &mlen, ct, clen)

5

EVP_PKEY_CTX_free(pkctx);

EVP_PKEY_CTX_free(pkctx);

加密(一步式)

解密(一步式)

1

EVP_PKEY_encrypt_old(

ct, msg, mlen, pkey);

EVP_PKEY_decrypt_old(

pt, ct, clen, pkey)

其中

  1. EVP_PKEY_CTX_newEVP_PKEY_CTX_free函数的使用说明请参见3.2 EVP_PKEY_CTXEVP_PKEY操作
  2. 剩余函数的说明见本节。

EVP_PKEY_encrypt_init

:   int EVP_PKEY_encrypt_init (EVP_PKEY_CTX *ctx); 

功能描述:   加密之前的EVP_PKEY_CTX初始化

    :   -

参数说明:

       ctx         (in/out)         EVP_PKEY_CTX

:   1[成功],<=0[失败]

EVP_PKEY_CTX_set_ec_enc_type

:   #define EVP_PKEY_CTX_set_ec_enc_type(ctx, type)

功能描述:   利用曲线类型设置加密/解密的曲线参数

    :   -

  1. 加密和解密之前都要调用该函数
  2. 便于后续利用对应的曲线参数生成密钥
  3. SM2type = NID_sm_scheme
  4. 调用EVP_PKEY_CTX_ctrl

参数说明:

       ctx         (in/out)         EVP_PKEY_CTX

       type              (in)               类型

:   1[成功],<=0[失败]

EVP_PKEY_encrypt

:   int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen);

功能描述:   加密

    :  

              1. 需一次性将数据送完

              2. 密文C1||C2||C3,其中C1共65字节,首字节为点的表示形式(如0x4)。

参数说明:

       ctx         (in/out)         EVP_PKEY_CTX

       out         (out)             密文(字符型)

       outlen    (out)             密文长度

       in           (in)               明文

       inlen      (in)               明文长度

:   1[成功],<=0[失败]

EVP_PKEY_encrypt_old

:   int EVP_PKEY_encrypt_old(unsigned char *out, const unsigned char *in, int inlen, EVP_PKEY *pub_key);

功能描述:   加密(一次性完成)

    :  

  1. 需一次性将数据送完
  2. 密文C1||C2||C3 C165字节,首字节为点的表示形式(如0x4)。
  3. 由于接口缺少type参数(曲线类型),因此内置type= NID_sm_scheme
  4. 将加密的整个流程封装在一起。如果pub_keyRSA类型的密钥,执行RSA加密。否则执行标准的SM2加密,流程如下。

a)    ctx = EVP_PKEY_CTX_new(pkey, NULL)

b)    EVP_PKEY_encrypt_init(ctx)

c)    EVP_PKEY_CTX_set_ec_enc_type(ctx, NID_sm_scheme)

d)    EVP_PKEY_encrypt(ctx, out, &size, in, inlen)

e)    EVP_PKEY_CTX_free(ctx);

参数说明:  

       out         (out)             密文(字符型)

       in           (in)               明文

       inlen      (in)               明文长度

       pub_key (in)               密钥

:   >=1[密文长度]<=0[失败]

EVP_PKEY_decrypt_init

:   int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx);

功能描述:   解密之前的EVP_PKEY_CTX初始化

    :   -

参数说明:

       ctx         (in/out)         EVP_PKEY_CTX

:   1[成功],<=0[失败]

EVP_PKEY_decrypt

:   int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen);

功能描述:   解密

    :  

              1. 需一次性将数据送完

              2. 密文C1||C2||C3,其中C1共65字节,首字节为点的表示形式(如0x4)。

参数说明:

       ctx         (in/out)         EVP_PKEY_CTX

       out         (out)             明文(字符型)

       outlen    (out)             明文长度

       in           (in)               密文

       inlen      (in)               密文长度

:   1[成功],<=0[失败]

EVP_PKEY_decrypt_old

:   int EVP_PKEY_decrypt_old(unsigned char *out, const unsigned char *in, int inlen, EVP_PKEY *pkey)

功能描述:   解密(一次性完成)

    :  

  1. 需一次性将数据送完
  2. 密文C1||C2||C3 C165字节,首字节为点的表示形式(如0x4)。
  3. 由于接口缺少type参数(曲线类型),因此内置type= NID_sm_scheme
  4. 将解密的整个流程封装在一起。如果pub_keyRSA类型的密钥,执行RSA加密。否则执行标准的SM2解密,流程如下。

a)    ctx = EVP_PKEY_CTX_new(pkey, NULL)

b)    EVP_PKEY_decrypt_init(ctx)

c)    EVP_PKEY_CTX_set_ec_enc_type(ctx, NID_sm_scheme)

d)    EVP_PKEY_decrypt(ctx, out, &size, in, inlen)

e)    EVP_PKEY_CTX_free(ctx);

参数说明: 

       out         (out)             明文(字符型)

       in           (in)               密文

       inlen      (in)               密文长度

       pub_key (in)               密钥

:   >=1[明文长度]<=0[失败]

加密解密示例代码

注意:其中密钥EVP_PKEY *pkey的生成代码参见密钥生成代码示例

#define DEAL_ERR(lab)\

        fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);\

        goto lab;

int test_evp_pkey_encrypt(EVP_PKEY *pkey, int do_sm2 )

{

        int ret = 0;

        EVP_PKEY_CTX *pkctx = NULL;

        int type = do_sm2 ? NID_sm_scheme : NID_secg_scheme;

        unsigned char msg[] = "hello world this is the message";

        size_t msglen = sizeof(msg);

        unsigned char cbuf[512];

        size_t cbuflen = sizeof(cbuf);

        unsigned char mbuf[512];

        size_t mbuflen = sizeof(mbuf);

        int len;

        unsigned int ulen;

        if (!(pkctx = EVP_PKEY_CTX_new(pkey, NULL)))   {DEAL_ERR(end);}

        if (!EVP_PKEY_encrypt_init(pkctx))                            {DEAL_ERR(end);}

        if (!EVP_PKEY_CTX_set_ec_enc_type(pkctx, type)) {DEAL_ERR(end);}

        cbuflen = sizeof(cbuf);

        if (!EVP_PKEY_encrypt(pkctx, cbuf, &cbuflen, msg, msglen))        {DEAL_ERR(end);}

        if (!EVP_PKEY_decrypt_init(pkctx))   {DEAL_ERR(end);}

        if (!EVP_PKEY_CTX_set_ec_enc_type(pkctx, type))         {DEAL_ERR(end);}

        memset(mbuf, 0, sizeof(mbuf));

        mbuflen = sizeof(mbuf);

        if (!EVP_PKEY_decrypt(pkctx, mbuf, &mbuflen, cbuf, cbuflen))        {DEAL_ERR(end);}

        ret = 1;

end:

        EVP_PKEY_CTX_free(pkctx);

        return ret;

}

#define DEAL_ERR(lab)\

        fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);\

        goto lab;

int test_evp_pkey_encdec_old(EVP_PKEY *pkey )

{

        int ret = 0;

        unsigned char msg[] = "hello world this is the message";

        size_t msglen = sizeof(msg);

        unsigned char cbuf[512];

        size_t cbuflen = sizeof(cbuf);

        unsigned char mbuf[512];

        size_t mbuflen = sizeof(mbuf);

        int len;

        if ((len = EVP_PKEY_encrypt_old(cbuf, msg,(int)msglen, pkey)) <= 0) {DEAL_ERR(end);}

        memset(mbuf, 0, sizeof(mbuf));

        if ((len = EVP_PKEY_decrypt_old(mbuf, cbuf, len, pkey)) <= 0) {DEAL_ERR(end);}

       

        printf("%s() passed!\n", __FUNCTION__);

        ret = 1;

end:

        return ret;

}

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号