Случайные символы при извлечении частного / публичного KEY (OpenSSL) из файла - PullRequest
4 голосов
/ 06 мая 2011

Я пытаюсь создать программу, которая после генерации пары открытый / закрытый ключ с помощью функции EC OppenSSL EC_KEY_generate_key хранит их в отдельных файлах и извлекает их для генерации ECDH KEY.Я сохраняю их правильно (без каких-либо дополнительных символов), когда я читаю файл и пытаюсь преобразовать шестнадцатеричные символы в BIGNUM, символ «04» или «00» появляется случайно (или даже иногда нет).Поэтому, когда я пытаюсь установить открытый / закрытый ключи и проверять весь ключ, происходит сбой.Может ли кто-нибудь помочь мне с этим вопросом?Может ли сбой проверки ключа быть вызван этими символами, или они нормальные?

Вот мой код, который генерирует / хранит закрытый ключ (открытый тот же самый):

    EC_KEY *b = NULL;
const BIGNUM *ppriv_b;
FILE *claveprivb;
const EC_GROUP *group;

b = EC_KEY_new_by_curve_name(NID_X9_62_prime192v1);
group = EC_KEY_get0_group(b);

EC_KEY_generate_key(b);
    claveprivb = fopen("/tmp/mnt/claveprivb", "w+");
    ppriv_b = EC_KEY_get0_private_key(b);
if ((ppriv_b != NULL)) 
    BN_print_fp(claveprivb,ppriv_b);
    fclose(claveprivb);

    //Afterwards do the same with the public key

А вот мой код для получения закрытого ключа:

    int i, s, blen, bout, ret = 0;
unsigned char *bbuf;
FILE *clavepriv, *clavetotalb;
const char cpriv_string[PRIVATE_KEY_SIZE];
BIGNUM *priv;
EC_KEY *b = NULL;
const EC_GROUP *groupb;

    b = EC_KEY_new_by_curve_name(NID_X9_62_prime192v1);
groupb = EC_KEY_get0_group(b);
    //Open the file with the hexadecimals (PRIVATE KEY)
    clavepriv = fopen("/tmp/mnt/claveprivb", "r");
kk2 = fread(&cpriv_string, sizeof(char), PRIVATE_KEY_SIZE, clavepriv);

priv = BN_new();
    //THIS FUNCTION (HEX2BN) GENERATES THE RANDOM CHARACTER: 
kk2 = BN_hex2bn(&priv, cpriv_string);
ret = EC_KEY_set_private_key(b, priv);

    //HERE I retrieve the public key by the same way and set it into EC_KEY b,
    //the same random character appears in the public key

    if (!EC_KEY_check_key(b)) {
    printf("EC_KEY_check_key failed\n");
} else {
    printf("Key verified OK\n");
}
    //It fails when try to check it.

int k;
clavetotalb = fopen("/tmp/mnt/clavetotalb", "w+");
k = EC_KEY_print_fp(clavetotalb, b, 0);

bout = ECDH_compute_key(bbuf, blen, EC_KEY_get0_public_key(b), b,
        KDF1_SHA1);

Любой совет будет очень признателен !!!! Спасибо !!!

После того, как я прочитал ответ на пост, я попыталсяиспользовать эти методы для декодирования и кодирования открытого ключа, но к тому времени, когда я пытаюсь вычислить ключ ECDH, я получаю ошибку сегментации.Цель моей программы - сгенерировать два ключа EC, записать их в несколько файлов, а затем извлечь их и вычислить с ними ключ ECDH.Вот список вещей, которые я изменяю из моей исходной программы в первом потоке, пожалуйста, скажите мне, если что-то не так:

* Generate EC key (public & private)
* Decode the private key with i2d_ECPrivatekey()
* Decode the public key with i2o_ECPublickey()
* Write them into several files.
* Read the file with the public key.
* Encode it with o2i_ECPublickey()
* Read the file with the private key.
* Encode it with d2i_ECPrivatekey().
* Compute the ECDH key.(Here is where I get the segmentation fault)

Я сыт по горло этой библиотекой OpenSSL ... это такнедоступен для начинающих пользователей ...

1 Ответ

5 голосов
/ 06 мая 2011

Открытый ключ EC , а не целое число;это точка кривой , которую можно представить как пару целых чисел.Эти два целых числа являются координатами точки (часто называемыми X и Y ).

Некоторые обозначения: кривая определена в конечном поле.Элементы конечного поля могут быть сопоставлены с целыми числами от 0 до q-1 , где q - размер поля (в случае используемой кривой, q - простое целое число, немного меньшее, чем 2 192 ).Пусть n будет размером байтов из q-1 : это размер беззнакового представления с прямым порядком байтов q-1 а именно целое число такое, что 2 8 (n-1) <= q-1 <2 <sup>8n .Для вашей кривой n = 24 .

С этими обозначениями стандартное представление точки кривой состоит ровно из 1 + 2n байтов, которые в этомпорядок:

  • байт значения 0x04
  • беззнаковое старшее порядковое представление x свыше n байтов
  • беззнаковое старшее порядковое представление y более n байт

Так что это объясняет ваш дополнительный байт '0x04';также, поскольку x и y должны кодироваться с точностью до n байтов, это может привести к принудительному включению дополнительных байтов '0x00', в случае, если их фактическое значение становится равнымбудет меньше, чем 2 8 (n-1) (с вашей кривой это должно быть в среднем примерно для 1/128 открытых ключей).

Существуют и другие варианты этого представления ( сжатые , в которых общий размер равен 1 + n , а первый байт равен 0x02 или 0x03, а hybrid , размером 1 + 2n , где первый байт равен 0x06 или 0x07), но они считаются необязательными в стандарте ECDSA (X9.62-2005), и ходят слухи, что сжатый форматзапатентовано.

Итог: если вы хотите кодировать и декодировать открытые ключи EC, вы должны смотреть на o2i_ECPublicKey() и i2o_ECPublicKey() и обрабатывать их как последовательность произвольных байтов, а не кодированных целых чисел.

...