Проверка подписи C++ DSS в PHP

У меня есть приложение C++ для подписи и проверки некоторых данных, теперь я хочу проверить данные в PHP, ниже приведен мой код C++ для подписи данных:

extern "C" __declspec(dllexport) BYTE* Sign(BYTE* bytdata)
{
    // Private key blob
    BYTE prKeyBlob[] = {7 , 2 , 0 , 0 , 0 , 34 , 0 , 0 , ...};

    HCRYPTPROV hProv = NULL;
    HCRYPTKEY prKey;
    HCRYPTHASH hHash;
    DWORD SignLen;

    if(CryptAcquireContext(&hProv, NULL, NULL, PROV_DSS, CRYPT_VERIFYCONTEXT)) 
// Creating cryptography provider
    {
        // Importing public key
        if(!CryptImportKey(hProv, prKeyBlob, sizeof(prKeyBlob), 0, 0, &prKey))
            return NULL;

        // Creating hash object
        if(!CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash))
            return NULL;

        if(!CryptHashData(hHash, bytdata, DATALEN, 0))
            return NULL;

        // Signing hashed value
        if(!CryptSignHash(hHash, AT_SIGNATURE, NULL, 0, NULL, &SignLen))
            return NULL;

        BYTE* bytSign = (BYTE*)malloc(SignLen);
        if(CryptSignHash(hHash, AT_SIGNATURE, NULL, 0, bytSign, &SignLen))
            return bytSign;
        else
            return NULL;
    }
    else
        return NULL;
}

Я пробовал PHP openssl_verify(), но не могу правильно передать открытый ключ; в С++ у меня есть байтовый массив большого двоичного объекта с открытым ключом, но я не знаю, как извлечь открытый ключ из этого массива и использовать его с php openssl.

function verify($data, $sign)
{
    // fetch public key from certificate and ready it
    $cert = file_get_contents('./key.pem');
    $pubkeyid = openssl_get_publickey($cert) or die("KEY ERROR");

    // state whether signature is okay or not
    return openssl_verify($data, $sign, $pubkeyid, OPENSSL_ALGO_DSS1)?1:0;
}

Но я получаю «ошибка: 0906D06C: подпрограммы PEM: PEM_read_bio: нет стартовой строки» от openssl_get_publickey

содержимое моего файла key.pem:

-----BEGIN PUBLIC KEY-----
fkNkBaO1Y0ZruN8LD8BGm3IF00bbSNZN/ql8ak0duOjbzDP229rnkPFDIPihbO
9Uw6369b3suwqvPY3w+VzwRKKfLG99KiMxMgF3H3IvJl8hyzQf6qJGJ9X
sonzhrTqDeugT9fa2FnpY5pg+7g+6MqSRh1T0qTii9JFcwVf5r/o=
-----END PUBLIC KEY-----

Заранее спасибо.


person Hamed Forsi    schedule 16.11.2013    source источник
comment
Это не форум, который позволяет вам получать реализации бесплатно. Пожалуйста, покажите нам, что вы пробовали. Я пробовал PHP openssl_verify(), но я не могу правильно передать открытый ключ, это не очень похоже на описание ошибки.   -  person Maarten Bodewes    schedule 16.11.2013


Ответы (1)


В документации по PHP есть четкое указание, что не так. PHP извлекает открытый ключ из сертификата, если вы используете openssl_get_publickey. К сожалению, у вас нет сертификата, у вас есть только открытый ключ.

Таким образом, есть два варианта: создать (самоподписанный?) сертификат вокруг вашего открытого ключа или найти функцию в PHP, которая считывает открытый ключ, закодированный PEM. К сожалению, эта последняя функция, похоже, отсутствует в действии.

person Maarten Bodewes    schedule 27.11.2013
comment
Спасибо за ваш ответ, моя проблема заключалась в том, что я не мог преобразовать свой большой двоичный объект с открытым ключом в pem или сертификат или наоборот, однако я изменил свой код C++ и использовал библиотеку openssl для C++ для решения проблемы. - person Hamed Forsi; 27.11.2013