2

我是密码学(openssl 库)的初学者,我需要有关如何通过 C 套接字通信发送 ECDSA 签名的帮助。我的计划是:

  1. 建立套接字连接
  2. 将 ECDSA SIG 对象转换为字符串
  3. 以字符串形式发送签名
  4. 在目的地,将字符串转换回 SIG 对象并验证签名

这是代码。

static ECDSA_SIG* sig = NULL;
static EC_KEY    *eckey = NULL;

 int main(int argc, char *argv[])
{         
    unsigned char* msgDigest = "6df19ccf6b89397c9a9906bfd0848f061352e9b5";
    if(ECDSAsign()) 
        printf("signed successfully\n");
    else
        printf("signing failed\n"); 

    ...
}

int ECDSAsign()
{
    int ret;

    eckey = EC_KEY_new_by_curve_name(NID_secp192k1);
    if (eckey == NULL)
    {
        printf(" error ");
        return 0;
    }

    if (!EC_KEY_generate_key(eckey))
    {
        printf(" error ");
        return 0;
    }

     unsigned char *buffer, *pp;
     int bufLen;
     bufLen = ECDSA_size(eckey);
     buffer = OPENSSL_malloc(bufLen);
     pp = buffer;
     unsigned char *dgst = "5df19ccf6b89397c9a9906bfd0848f061352e9ba";
     sig = ECDSA_do_sign(dgst, strlen(dgst), eckey);
     if (sig == NULL)
     {
        printf(" Signature NOT generated\n ");
        return 0;
     }

    return 1;
}
4

1 回答 1

0

如何将 ECDSA SIG 签名转换为 C 中的字符数组
...

签名已经是一个字节数组。那就是从EVP_DigestSignFinal.


通常,您希望使用EVP_*接口进行签名和验证。以下是关于EVP 签名和验证的 OpenSSL wiki 。

您在下面的工作是将 ECDSA 放入EVP_PKEY*. 该函数将分配签名缓冲区OPENSSL_malloc。调用者需要使用 释放它OPENSSL_free。缓冲区是一个字节数组。

int sign_it(const byte* msg, size_t mlen, byte** sig, size_t* slen, EVP_PKEY* pkey)
{
    /* Returned to caller */
    int result = -1;

    if(!msg || !mlen || !sig || !pkey) {
        assert(0);
        return -1;
    }

    if(*sig)
        OPENSSL_free(*sig);

    *sig = NULL;
    *slen = 0;

    EVP_MD_CTX* ctx = NULL;

    do
    {
        ctx = EVP_MD_CTX_create();
        assert(ctx != NULL);
        if(ctx == NULL) {
            printf("EVP_MD_CTX_create failed, error 0x%lx\n", ERR_get_error());
            break; /* failed */
        }

        const EVP_MD* md = EVP_get_digestbyname("SHA256");
        assert(md != NULL);
        if(md == NULL) {
            printf("EVP_get_digestbyname failed, error 0x%lx\n", ERR_get_error());
            break; /* failed */
        }

        int rc = EVP_DigestInit_ex(ctx, md, NULL);
        assert(rc == 1);
        if(rc != 1) {
            printf("EVP_DigestInit_ex failed, error 0x%lx\n", ERR_get_error());
            break; /* failed */
        }

        rc = EVP_DigestSignInit(ctx, NULL, md, NULL, pkey);
        assert(rc == 1);
        if(rc != 1) {
            printf("EVP_DigestSignInit failed, error 0x%lx\n", ERR_get_error());
            break; /* failed */
        }

        rc = EVP_DigestSignUpdate(ctx, msg, mlen);
        assert(rc == 1);
        if(rc != 1) {
            printf("EVP_DigestSignUpdate failed, error 0x%lx\n", ERR_get_error());
            break; /* failed */
        }

        size_t req = 0;
        rc = EVP_DigestSignFinal(ctx, NULL, &req);
        assert(rc == 1);
        if(rc != 1) {
            printf("EVP_DigestSignFinal failed (1), error 0x%lx\n", ERR_get_error());
            break; /* failed */
        }

        assert(req > 0);
        if(!(req > 0)) {
            printf("EVP_DigestSignFinal failed (2), error 0x%lx\n", ERR_get_error());
            break; /* failed */
        }

        *sig = OPENSSL_malloc(req);
        assert(*sig != NULL);
        if(*sig == NULL) {
            printf("OPENSSL_malloc failed, error 0x%lx\n", ERR_get_error());
            break; /* failed */
        }

        *slen = req;
        rc = EVP_DigestSignFinal(ctx, *sig, slen);
        assert(rc == 1);
        if(rc != 1) {
            printf("EVP_DigestSignFinal failed (3), return code %d, error 0x%lx\n", rc, ERR_get_error());
            break; /* failed */
        }

        assert(req == *slen);
        if(rc != 1) {
            printf("EVP_DigestSignFinal failed, mismatched signature sizes %ld, %ld", req, *slen);
            break; /* failed */
        }

        result = 0;

    } while(0);

    if(ctx) {
        EVP_MD_CTX_destroy(ctx);
        ctx = NULL;
    }

    /* Convert to 0/1 result */
    return !!result;
}
于 2015-05-07T17:25:28.660 回答