Как преобразовать подпись ECDSA SIG в массив символов в C
Я новичок в криптографии (библиотека openssl), и мне нужна была помощь в том, как отправить подпись ECDSA через связь через сокет C. Мой план:
- сделать сокет соединение
- преобразовать объект ECDSA SIG в строку
- отправить подпись в виде строки
- В месте назначения преобразуйте строку обратно в объект 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;
}
1 ответ
Как преобразовать подпись ECDSA SIG в массив символов в C
...
Подпись уже является массивом байтов. Вот что возвращается EVP_DigestSignFinal
,
В общем, вы хотите использовать EVP_*
интерфейсы для подписи и проверки. Ниже из вики OpenSSL по подписи и проверке EVP.
Ваша работа ниже, чтобы получить 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;
}