Изменение порядкового номера пары закрытых / открытых ключей в кодировке PEM с целью использования CryptoAPI-совместимых подписей в libcrypto - PullRequest
0 голосов
/ 05 февраля 2019

Я пишу программу, которая может подписывать и проверять подписи, изначально созданные для 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?Я не хочу делать это вручную, так как это масштабируется.

...