2015-04-09 3 views
0

Я использую функцию RSA_verify() для проверки SHA, которую я подписал, с помощью программы openssl (через консоль). RSA_verify() всегда возвращает неудачную проверку, поэтому я думаю, что я отправляю ему неправильные параметры.'dgst проверить и подписать' эквивалент с 'RSA_Verify()'

Следующие команды консоли запускаются в Linux Ubuntu с OpenSSL 0.9.8k.

Функции C скомпилированы для Android, используя OpenSSL 1.0.1 ... c, насколько я помню. Это определенно 1.0.1 (мы обновляем его, чтобы избежать проблемы с кровотечением).

Это то, что я делаю ... прошу простить любую ошибку, поскольку я изучаю это самостоятельно.

  1. Генерация закрытый ключ

    openssl genrsa -out private.key 2048 
    
  2. Извлечения открытого ключа из закрытого ключа

    openssl rsa -in private.key -out public.key -outform PEM -pubout 
    
  3. Вычислить SHA из файла под названием разрешений, а затем подписать его с частным .key, выход будет SHA, но с RSA-шифрованием (permissions.sign)

    openssl dgst -sha256 -sign private.key -out permissions.sign permissions 
    
  4. Validate Принимаемый ША подписи против файла разрешений (это успешно в консоли Ubuntu)

    openssl dgst -sha256 -verify public.key -signature permissions.sign permissions 
    
  5. скопировать файл разрешений, в permissions.sign файл и файл public.key в файловой системы в Android.

  6. Я подтверждаю, что permissions.sign был создан с разрешениями и с соответствующим private.key ... все это с моим public.key (у меня нет закрытого ключа в Android).

Это функция C.

#include <openssl/pem.h> 
#include <openssl/rsa.h> 
#include <openssl/sha.h> 

... 

/* Initialize the public key */ 
RSA *pub_key = RSA_new(); 

if(NULL == pub_key) 
{ 
    ANDROID_LOGE("RSA_new failed"); 
    result = 0; 
} 
else 
{ 
    FILE* fp = fopen(public_key, "r"); 

    if(NULL == fp) 
    { 
     ANDROID_LOGE_P("fopen [%s] failed", public_key); 
     result = 0; 
    } 
    else 
    { 
     /* Read it from the passed path */ 
     if(PEM_read_RSA_PUBKEY(fp, &pub_key, NULL, NULL) == NULL) 
     { 
     ANDROID_LOGE_P("[%s] can't be read", public_key); 
     result = 0; 
     fclose(fp); 
     } 
     else 
     { 
     /* Verify the file and its SHA with the public key */ 
     int verified = RSA_verify(
      NID_sha256, 
      file, /* message digest (message to validate) */ 
      file_size, /* message size */ 
      sign, /* signature (signed SHA) */ 
      sign_size, /* signature size */ 
      pub_key); 
     ANDROID_LOGD("NID_sha256"); 

     if(verified) 
     { 
      result = 1; 
      ANDROID_LOGD_P("[%s] is valid", file_to_verify); 
     } 
     else 
     { 
      ANDROID_LOGE_P("[%s] is NOT valid", file_to_verify); 
     } 

     fclose(fp); 
     } 

     RSA_free(pub_key); 
    } 
} 
  • public_key это путь к public.key
  • PEM_read_RSA_PUBKEY успешно
  • NID_sha256 то, что я думаю, что я должен использовать для проверки
  • файла является массив байтов с содержимым разрешений
  • file_size - размер массива файла
  • знак представляет собой массив байтов с содержимым разрешений.знак
  • sign_size является размер массива знака
  • RSA_verify() терпит неудачу, она возвращает 0

Так что вопрос, правильно ли:

  • генерировать ключи с команды, которые я использовал,

  • подпись файла разрешений (который создает permissions.sign),

  • , а затем попробуйте проверить файлы с помощью PEM_read_RSA_PUBKEY() и RSA_verify()?

Являются ли команды, которые я использовал для процесса подписи, эквивалентными функциям C, которые я использовал для процесса проверки?

Пожалуйста, дайте мне знать, требуется ли дополнительная информация или где я мог бы узнать больше об этом.

Спасибо!

EDIT: Я добавил некоторые ошибки печати после вызова RSA_Verify():

ANDROID_LOGE_P ("OpenSSL:% S", ERR_reason_error_string (ERR_get_error()));

Он печатает:

OpenSSL: плохая подпись

еще расследуют.

+0

возможно ошибка в чтении в файлах? –

+0

Я проверил их, процесс чтения в порядке. Спасибо. –

+1

Команда OpenSSL рекомендует использовать функции 'EVP_DigestSign * 'и' EVP_DigestVerify * '. См. [Подписание и проверка EVP] (https://wiki.openssl.org/index.php/EVP_Signing_and_Verifying). Вики также предоставляет код, который вы можете скопировать/вставить, чтобы сделать это. – jww

ответ

1

В процессе чтения для открытого ключа было несколько недостающих шагов.

правильных команды для генерации закрытых и открытых ключей следующим образом:

Генерации закрытого ключ «OpenSSL genrsa -out private.key 2048»

Извлечения открытого ключа (формы сертификата МЭДА) от закрытого ключа (необходимой RSA_SHA_Verify()) "OpenSSL REQ -outform DER -new -x509 -key private.key -out public.key -days 30000"

Сформировать открытый ключ нет информации сертификата (только необходимо для «openssl dgst -sha1 -verify ...») " OpenSSL x509 информ DER -in public.key -pubkey -noout> public_no_cert.key»

Подписать файл с секретным ключом "OpenSSL dgst -sha1 -знак private.key -out permissions.sign разрешения"

Проверьте файл с открытым ключом (нет информации) сертификата «OpenSSL dgst -sha1 -verify public_no_cert.key -Подписание permissions.sign разрешения»

Пожалуйста, обратитесь к документации по OpenSSL.org для деталей. Я потребовал сертификат X509 DER, который держал открытый ключ, чтобы проверить подписанный SHA с RSA_verify().

равноценности в командном режиме для RSA_verify() является:

OpenSSL dgst -sha1 -verify public.key -Подписание permissions.sign разрешения

для исходного кода, пожалуйста, обратитесь к этой ссылке: http://www.bmt-online.org/geekisms/RSA_verify

Он НЕ компилируется с первого взгляда, вам нужно его подстроить. Вызовите следующие функции:

result = sign_data(
     input_file_buffer, 
     input_file_size, 
     private_key_buffer, 
     private_key_size, 
     (void**)&signature, 
     &signature_size); 

    result = verify_data(
     input_file_buffer, 
     input_file_size, 
     signature_buffer, 
     signature_size, 
     public_key_buffer, 
     public_key_size); 

Все должно быть в ОЗУ, передавать их в качестве указателей.

Функция подписи ожидает, что указатель на указатель (**) сохранит подписанный SHA. Вы можете впоследствии сохранить его в файл.

Протестировано под Ubuntu openssl 0.9.8k.

Если вы видите, что что-то отсутствует, сообщите мне. Спасибо за прочтение!

EDIT: Вот ссылка на исходный код ... http://migsantiago.com/index.php/tutoriales/32-firma-y-valida-archivos-con-openssl

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