Как использовать OpenSC для расшифровки сообщения с закрытым ключом со смарт-карты

Недавно мы обновились до OpenSC 0.15.0 и по какой-то причине мы больше не можем использовать его для расшифровки сообщения с закрытым ключом со смарт-карты.

По-видимому, то же самое происходит, если мы используем инструмент pkcs11 (при условии OpenSC) и механизм OpenSSL.

Ниже приведен пример того, что мы сделали:

PKCS11-инструмент:

% pkcs11-tool --module /usr/local/lib/opensc-pkcs11.so --decrypt -v -l --input-file encrypted.bin --id 9352
Using slot 1 with a present token (0x1)
Logging in to "OpenSC Card".
Please enter User PIN: 
Using decrypt algorithm RSA-PKCS
error: PKCS11 function C_Decrypt failed: rv = CKR_DATA_LEN_RANGE (0x21)

Aborting.

Или с использованием движка OpenSSL, вот небольшой пример программы:

#include <iostream>
#include <openssl/engine.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <openssl/crypto.h>

using namespace std;

int main()
{
    OpenSSL_add_all_algorithms();
    ENGINE_load_dynamic();

    // Setup OpenSSL engine
    ENGINE* engine = ENGINE_by_id("dynamic");
    string enginePath = "/usr/local/lib/engines/pkcs11.so";
    string modulePath = "/usr/local/lib/opensc-pkcs11.so";

    ENGINE_ctrl_cmd_string(engine, "SO_PATH", enginePath.c_str(), 0);
    ENGINE_ctrl_cmd_string(engine, "LIST_ADD", "1", 0);
    ENGINE_ctrl_cmd_string(engine, "LOAD", NULL, 0);
    ENGINE_ctrl_cmd_string(engine, "MODULE_PATH", modulePath.c_str(), 0);

    string pin = "123456";
    ENGINE_ctrl_cmd_string(engine, "PIN", pin.c_str(), 0);
    ENGINE_ctrl_cmd_string(engine, "VERBOSE", NULL, 0);
    ENGINE_init(engine);
    ENGINE_set_default(engine, ENGINE_METHOD_ALL);

    string keyName = "id_9352";
    EVP_PKEY *evp = ENGINE_load_private_key(engine, keyName.c_str(), NULL, NULL);

    // Read encrypted file
    long unsigned int length = 128;
    unsigned char buf[length];
    FILE* f = fopen("encrypted.bin", "r");
    fread(buf, 1, length, f);
    fclose(f);

    // Try to decrypt
    unsigned char output[length];
    unsigned char* p = output;
    RSA *rsa = EVP_PKEY_get1_RSA(evp);
    int outputLen = RSA_private_decrypt(length, buf, p, rsa, RSA_PKCS1_PADDING);
    if (outputLen == -1) {
        long err = ERR_get_error();
        cout << "Error decrypting: " << ERR_error_string(err, NULL) << endl;
        return 1;
    }

    cout << output << endl;
    return 0;
}

Но когда я запускаю это:

% ./sc-decrypt
PKCS#11: Initializing the engine
Found 2 slots
Loading private key "slot_1-id_9352"
Looking in slot 1 for key: 9352
[18446744073709551615] Virtual hotplug slot       no tok          
[1] Gemalto PC Twin Reader 00  login             (OpenSC Card)
Found slot:  Gemalto PC Twin Reader 00 00
Found token: OpenSC Card
Found 0 certificate:
Found 1 private key:
   1 P  Private Key
Error decrypting: error:80008021:Vendor defined:PKCS11_rsa_decrypt:Data len range

По всей видимости, в обоих случаях это одна и та же ошибка, что-то вроде "Data len range"

Что еще более странно, это то, что при использовании pkcs11-tool для операции подписи (которая также использует закрытый ключ) работает нормально:

% echo "test signing" > input.txt
% pkcs11-tool --module /usr/local/lib/opensc-pkcs11.so --sign -v --input-file input.txt --output-file out.sign --id 9352 -l
Using slot 1 with a present token (0x1)
Logging in to "OpenSC Card".
Please enter User PIN: 
Using signature algorithm RSA-PKCS
% ls -l out.sign 
-rw-------  1 user  user  128 May 18 10:08 out.sign

Так что, если кто-то может указать, что я делаю неправильно, я был бы очень благодарен

0 ответов

Я знаю, что это происходит довольно поздно (через 3 года после вопроса), но это может кому-то помочь.

Я столкнулся с той же проблемой. Но когда я перечисляю все механизмы, поддерживаемые OpenSC, я вижу, что минимальный размер ключа для RSA_PKCS 512, На самом деле, это размер модуля. Соответствующий размер ключа4096, Так что просто убедитесь, что ваша сгенерированная пара ключей, по крайней мере, 4096 биты длинные В моем случае это сработало (используя pkcs11-tool команда. Я еще не реализовал C код от этого).

Другие вопросы по тегам