PHP中的C ++ DSS签名验证

时间:2013-11-16 12:15:05

标签: php cryptography digital-signature cryptoapi php-openssl

我有一个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(),但我无法正确提供公钥;在C ++中,我有一个公钥blob的字节数组,但我不知道如何从这个数组中提取公钥,并将它与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;
}

但是我从openssl_get_publickey获得“错误:0906D06C:PEM例程:PEM_read_bio:无起始行”

我的key.pem文件内容:

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

提前谢谢。

1 个答案:

答案 0 :(得分:0)

PHP文档中有一个明确的指示是错误的。如果您使用openssl_get_publickey,PHP将从证书中检索公钥。不幸的是,你没有证书,只有公钥。

因此,有两种选择:围绕您的公钥创建(自签名?)证书,或者在PHP中查找读取PEM编码公钥的函数。不幸的是,最后一个功能似乎在行动中缺失。