Подписание сообщения с использованием ECDSA в OpenSSL - PullRequest
3 голосов
/ 09 февраля 2010

Как мне установить закрытый ключ для подписи сообщений при использовании ECDSA в OpenSSL программно? У меня есть следующий код:

static int create_signature(unsigned char* hash)
{
  EC_KEY *eckey=NULL;
  EC_GROUP *ecgroup=NULL;
  EVP_PKEY *evpkey=NULL;
  unsigned char *signature=NULL;
  point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
  int signature_size, block_size;
  unsigned char * block=NULL;

  ecgroup = get_ec_group_192();
  EC_GROUP_set_asn1_flag(ecgroup, OPENSSL_EC_NAMED_CURVE);
  EC_GROUP_set_point_conversion_form(ecgroup, form);
  eckey=EC_KEY_new();
  EC_KEY_set_group(eckey,ecgroup);
  EC_KEY_generate_key(eckey);
  evpkey=EVP_PKEY_new();
  EVP_PKEY_assign_EC_KEY(evpkey,eckey);
  signature=OPENSSL_malloc(EVP_PKEY_size(evpkey));

  ECDSA_sign(0, hash, sizeof(hash), signature, &signature_size, eckey);

  printf("%s", signature);
  return 0;
}

Функция get_ec_group_192() создается путем запуска openssl ecparam -C -name secp192k1 -genkey, который также генерирует некоторые EC PARAMETERS и EC PRIVATE KEY.

Я пытаюсь зашифровать сообщение, содержащееся в hash, с помощью моего личного ключа, чтобы его мог расшифровать только открытый ключ. Возможно ли это с помощью приведенного выше кода, или я делаю это совершенно неправильно?

Ответы [ 2 ]

7 голосов
/ 15 мая 2011

Для меня успешно подтверждается следующее:

//compiled with gcc -g -lssl -UOPENSSL_NO_EC SO2228860.c -lcrypto
#include <openssl/ec.h>      // for EC_GROUP_new_by_curve_name, EC_GROUP_free, EC_KEY_new, EC_KEY_set_group, EC_KEY_generate_key, EC_KEY_free
#include <openssl/ecdsa.h>   // for ECDSA_do_sign, ECDSA_do_verify
#include <openssl/obj_mac.h> // for NID_secp192k1


static int create_signature(unsigned char* hash)
{
    int function_status = -1;
    EC_KEY *eckey=EC_KEY_new();
    if (NULL == eckey)
    {
        printf("Failed to create new EC Key\n");
        function_status = -1;
    }
    else
    {
        EC_GROUP *ecgroup= EC_GROUP_new_by_curve_name(NID_secp192k1);
        if (NULL == ecgroup)
        {
            printf("Failed to create new EC Group\n");
            function_status = -1;
        }
        else
        {
            int set_group_status = EC_KEY_set_group(eckey,ecgroup);
            const int set_group_success = 1;
            if (set_group_success != set_group_status)
            {
                printf("Failed to set group for EC Key\n");
                function_status = -1;
            }
            else
            {
                const int gen_success = 1;
                int gen_status = EC_KEY_generate_key(eckey);
                if (gen_success != gen_status)
                {
                    printf("Failed to generate EC Key\n");
                    function_status = -1;
                }
                else
                {
                    ECDSA_SIG *signature = ECDSA_do_sign(hash, strlen(hash), eckey);
                    if (NULL == signature)
                    {
                        printf("Failed to generate EC Signature\n");
                        function_status = -1;
                    }
                    else
                    {

                        int verify_status = ECDSA_do_verify(hash, strlen(hash), signature, eckey);
                        const int verify_success = 1;
                        if (verify_success != verify_status)
                        {
                            printf("Failed to verify EC Signature\n");
                            function_status = -1;
                        }
                        else
                        {
                            printf("Verifed EC Signature\n");
                            function_status = 1;
                        }
                    }
                }
            }
            EC_GROUP_free(ecgroup);
        }
        EC_KEY_free(eckey);
    }

  return function_status;
}

int main( int argc , char * argv[] )
{
    unsigned char hash[] = "c7fbca202a95a570285e3d700eb04ca2";
    int status = create_signature(hash);
    return(0) ;
}
2 голосов
/ 12 июля 2018

Это небольшая ошибка в приведенном выше коде.Переданный хеш - это беззнаковый символ, этот хэш МОЖЕТ содержать 0x00 значений!НЕ используйте strlen (хеш) для вычисления длины, так как это, возможно, передаст неверную длину подпрограмме, если хеш имеет 0x00 в любом месте.Хэши имеют фиксированную длину и должны быть переданы как таковые.Например, sha256 должен иметь длину 64.

...