Я пишу программу, которая может подписывать и проверять подписи, изначально созданные для CryptoAPI (старая библиотека шифрования Windows).Цель состоит в том, чтобы иметь возможность подписывать / проверять из linux.
Однако, похоже, я бью стену из-за того, что CryptoAPI и libcrypto имеют разные порядковые номера.
Я уже пытался изменить порядок проверяемой подписи (весь 128-байтовый RSA-зашифрованный кусок с заполнением и все).Этого, кажется, недостаточно, и я изо всех сил пытаюсь найти правильный прямой рецепт, чтобы сделать это легко.
Я обнаружил в другом посте stackoverflow, что вам нужно обратить вспять порядковый номер фактического ключа.Поэтому мне интересно, есть ли какой-нибудь простой способ сделать это, где мне предпочтительно не нужно возиться с данными самостоятельно.
Я буду придерживаться проверки, поскольку я предполагаю, что тот же рабочий процесс может быть применен к закрытому ключу PEM.Ситуация выглядит следующим образом:
У меня есть открытый ключ в качестве PEM, преобразованный с помощью команды
openssl rsa -pubin -inform MS\ PUBLICKEYBLOB -in pkey_mspublic.bin -outform PEM -out pubkey.pem
Ниже показано, как загрузить PEM в libcrypto и проверить подпись:
BIO* certBio = BIO_new_mem_buf((void*)pubkey, -1);
RSA* rsa = NULL;
rsa = PEM_read_bio_RSA_PUBKEY(certBio, &rsa,NULL, NULL);
for (int i=0; i <signatureLength; i++)
{
char tmp = expectedHashPtr[i];
expectedHashPtr[i] = expectedHashPtr[signatureLength - 1 - i];
expectedHashPtr[signatureLength - 1 - i] = tmp;
}
EVP_PKEY* pubKey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(pubKey, rsa);
std::cout << "pubkey size: " << EVP_PKEY_size(pubKey) << std::endl;
EVP_MD_CTX* mdctx = EVP_MD_CTX_create();
if(!(mdctx = EVP_MD_CTX_create())) std::cout << "ctx create fail" << std::endl;
if(1 != EVP_VerifyInit(mdctx, EVP_md5())) std::cout << "digest init fail" << std::endl;
if(1 != EVP_VerifyUpdate(mdctx, data, 512)) std::cout << "digest fail" << std::endl;
std::cout << "finishing verify" << std::endl;
if(1 == EVP_VerifyFinal(mdctx, (unsigned char*)expectedHashPtr, signatureLength, pubKey))
{
/* Success */
std::cout << "Success" << std::endl;
return true;
}
else
{
ERR_print_errors_fp(stderr);
std::cout << "Fail" << std::endl;
return false;
}
Когда я запускаю приведенный выше код, я получаю ошибки заполнения, которые, как мне кажется, происходят из-за того, что мой ключ неверный, а потому неправильный:
140278264301376:error:0407008A:rsa routines:RSA_padding_check_PKCS1_type_1:invalid padding:crypto/rsa/rsa_pk1.c:67:
140278264301376:error:04067072:rsa routines:rsa_ossl_public_decrypt:padding check failed:crypto/rsa/rsa_ossl.c:582:
Итак, мой вопросЕсть ли быстрый и простой способ обработки бесконечности преобразования открытого и закрытого ключа в формате PEM?Я не хочу делать это вручную, так как это масштабируется.