2013-04-25 4 views
5

Я пытаюсь написать код, чтобы проверить некоторые подписи RSA. Подписи были сделаны с помощью инструмента OpenSSL командной строки, используя эквивалент этой командной строки:Проверка подписи RSAS OpenSSL: хэш и отступы?

openssl dgst -sha1 -sign private_key_file.pem <binary_data_file> sig 

Я пытаюсь использовать libtomcrypt сделать проверить:

http://www.libtom.org/

Вот вызов сигнатуры функции проверки RSA в libtomcrypt:

int rsa_verify_hash_ex(
    const unsigned char *sig, unsigned long siglen, // signature to verify 
    const unsigned char *hash, unsigned long hashlen, // hash value to check against sig 
    int padding, // defined constant value, see below 
    int hash_idx, // identifies which hash algorithm, see below 
    unsigned long saltlen, // specify salt length, see below 
    int *stat, // output parameter, returns whether verify succeeded or not 
    rsa_key *key); // RSA public key to use for verify 

Эта функция возвращает 0, если он работает без ошибок, иначе возвращает код ошибки. Если он работает без ошибок, выходной параметр stat указывает, проверена ли подпись.

Большинство аргументов кажутся простыми: передайте подпись, чтобы проверить, значение хэша использовать для сравнения, и ключ RSA для использования для проверки. hash_idx ясно из примера кода, прилагаемого к libtomcrypt; это индекс в таблицу поддерживаемых алгоритмов хэширования, и я могу найти правильное значение для использования с этим фрагментом коды: hash_idx = find_hash("sha1")

Но я задаюсь вопрос о ценностях padding и saltlen. padding меня не слишком беспокоит, так как есть только два возможных значения, и я могу просто попробовать их обоих. Но что я должен пройти за saltlen?

Документация OpenSSL для функций OpenSSL для проверки RSA не показывает параметр saltlen. Страница руководства для openssl dgst (т. Е. Результат man dgst) не обсуждает соль.

Так мои вопросы:

  • Как я могу определить правильную длину соли использовать?
  • вставить ли команда OpenSSL, dgst любой дополнительный материал на входе, таких как: (stdin)=

(я обнаружил, что (stdin)= вещь путем поиска StackOverflow: Why are the RSA-SHA256 signatures I generate with OpenSSL and Java different?)

  • libtomcrypt также имеет функцию под названием pkcs_1_pss_decode() который документирован, чтобы «декодировать закодированный PSS-блок». Есть ли вероятность, что это функция, которую мне нужно позвонить?

Спасибо за любую помощь, которую вы можете мне дать.

EDIT: благодаря помощи ниже, от @Jonathan Ben-Avraham, я смог получить эту работу сегодня. Ответы на мои вопросы:

  • Использовать длину 0 для соли, без соли.
  • Нет, OpenSSL не ничего лишнего вставки, такие как (stdin)=
  • мне нужно позвонить rsa_verify_hash_ex(), и мне нужно было указать padding аргумент LTC_LTC_PKCS_1_V1_5.

ответ

7

Нет соли:

Во-первых, не генерировать двоичный SHA1 хэш ваших данных:

openssl dgst -sha1 -binary -out hash1 some_data_file 

Это SHA1 хэш или переварить. В файле some_data_file отсутствует соль. Сам openssl dgst -sha1 не добавляет соли. Обратите внимание, что выходной файл представляет собой только 20-байтовый SHA1-хэш без соли. Если бы существовала соль, хэш должен был бы включать ее, вероятно, предварительно до 20 байтов, содержащих хэш SHA1.

Далее подписать SHA1 хэш файла hash1 с закрытым ключом:

openssl pkeyutl -sign -in hash1 -inkey privkey.pem -pkeyopt digest:sha1 -out sig1 

Теперь подпишите some_data_file с openssl dgst:

openssl dgst -sha1 -sign privkey.pem <some_data_file> sig2 

Наконец, сравните две подписи:

diff sig1 sig2 

, и вы должны увидеть, что они являются одна и та же. Это говорит нам о том, что подписание сырого SHA1-хэша файла без соли - это то же самое, что и команда openssl dgst -sha1 -sign для подписания файла, поэтому должно быть указано, что команда openssl dgst -sha1 -sign также не использовала соль при создании своего SHA1-хэша для sig2.

Заметим также, что вы не можете достичь того же результата, используя устаревшую rsautl:

openssl rsautl -sign -in hash1 -inkey privkey.pem -out sig1 

вместо openssl pkeyutl, по-видимому, потому, что openssl rsautl -sign включает в себя зашифрованный текст в выходных данных, а также подпись. См. this SE post.

+0

Благодарим за отличный ответ. Вы дали мне инструменты, чтобы убедиться, что нет соли. У меня теперь есть код 'libtomcrypt', который успешно проверяет подписи! +1 и ответ принят. – steveha

+0

@steveha: Спасибо! Вы также можете просмотреть более позднюю запись, касающуюся '' rsautl'': http://stackoverflow.com/questions/9951559/difference-between-openssl-rsautl-and-dgst –

3

Следует подчеркнуть: обязательно передайте хэш-код вместо фактических данных. Это отбросило меня на некоторое время. Вот фрагмент, который работает (но используйте sha256):

void 
verify_tomcrypt(unsigned char *keyblob, size_t klen, 
       unsigned char *payload, size_t dlen, 
       unsigned char *signature, size_t slen) 
{ 
    rsa_key key; 
    int stat; 
    unsigned long len; 
    unsigned char digest2[SHA256_DIGEST_LENGTH]; 

    ltc_mp = ltm_desc; 
    register_hash(&sha256_desc); 

    /* try reading the key */ 
    if (rsa_import(keyblob, klen, &key) != CRYPT_OK) { 
     printf("Error reading key\n"); 
     exit(-1); 
    } 

    int hash_idx = find_hash("sha256"); 
    if (hash_idx == -1) { 
     printf("LTC_SHA256 not found...?\n"); 
     exit(-1); 
    } 
    len = sizeof(digest2); 
    if (hash_memory(hash_idx, payload, dlen, digest2, &len) != CRYPT_OK) { 
     printf("sha256 fails...?\n"); 
     exit(-1); 
    } 

    if (rsa_verify_hash_ex(signature, slen, digest2, sizeof(digest2), LTC_LTC_PKCS_1_V1_5, hash_idx, 0, &stat, &key) == CRYPT_OK) { 
     if (stat == 1) 
      printf("Tomcrypt: Signature OK!\n"); 
     else 
      printf("Tomcrypt: Signature NOK?\n"); 
    } else { 
     printf("Tomcrypt: Signature error\n"); 
    } 
} 
+0

Спасибо за образец кода. –

+0

Я получаю 'CRYPT_PK_INVALID_SIZE' за конкретную проверку rsa sig. В чем проблема? эта ошибка возвращается 'rsa_verify_hash_ex' –

Смежные вопросы