Я использую функцию 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 (мы обновляем его, чтобы избежать проблемы с кровотечением).
Это то, что я делаю ... прошу простить любую ошибку, поскольку я изучаю это самостоятельно.
Генерация закрытый ключ
openssl genrsa -out private.key 2048
Извлечения открытого ключа из закрытого ключа
openssl rsa -in private.key -out public.key -outform PEM -pubout
Вычислить SHA из файла под названием разрешений, а затем подписать его с частным .key, выход будет SHA, но с RSA-шифрованием (permissions.sign)
openssl dgst -sha256 -sign private.key -out permissions.sign permissions
Validate Принимаемый ША подписи против файла разрешений (это успешно в консоли Ubuntu)
openssl dgst -sha256 -verify public.key -signature permissions.sign permissions
скопировать файл разрешений, в permissions.sign файл и файл public.key в файловой системы в Android.
Я подтверждаю, что 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: плохая подпись
еще расследуют.
возможно ошибка в чтении в файлах? –
Я проверил их, процесс чтения в порядке. Спасибо. –
Команда OpenSSL рекомендует использовать функции 'EVP_DigestSign * 'и' EVP_DigestVerify * '. См. [Подписание и проверка EVP] (https://wiki.openssl.org/index.php/EVP_Signing_and_Verifying). Вики также предоставляет код, который вы можете скопировать/вставить, чтобы сделать это. – jww