簡體   English   中英

從“ google inapp billing”給出的公鑰開始EVP_PKEY(在opensssl中)

[英]Initailzing EVP_PKEY(in opensssl) from public key given by 'google inapp billing'

我縮進以驗證在服務器端實施的C或C ++中的“ google inapp結算簽名”

我找到了通過php( php服務器中的Android應用內帳單簽名驗證 )的方法,並建議它可以使用openssl ..中的EVP_Verify ...函數,但要使用:

int EVP_VerifyFinal(EVP_MD_CTX * ctx,unsigned char * sigbuf,unsigned int siglen,EVP_PKEY * pkey);

它需要'EVP_PKEY * pkey'結構的實例作為參數...但是我沒有它!

我相信有一種方法可以將“ Google InApp Billing簽名字符串(使用PKCS#1填充的base64編碼的SHA1-with-RAS簽名)”轉換為EVP_PKEY ..但我不知道該怎么做。

我如何通過它作為EVP_VerifyFinal函數的參數?

int main()
{
    OPENSSL_config(NULL);
    OpenSSL_add_all_digests();
    ERR_load_crypto_strings();

    EVP_MD_CTX* ctx = EVP_MD_CTX_create();
    const EVP_MD* md = EVP_get_digestbyname("SHA1");
    if(0 == EVP_VerifyInit_ex(ctx, md, NULL))
    {
        std::cerr << "init error" << std::endl;
        return 0;
    }

    const char* data = "{\"orderId\":\"12999763169054705758.1310724241212373\",\"packageName\":\"com.company.game.google\",\"productId\":\"game_product_001\",\"purchaseTime\":1358227642000,\"purchaseState\":0,\"developerPayload\":\"12322144\",\"purchaseToken\":\"}";
    if(0 == EVP_VerifyUpdate(ctx, (void*)data, strlen(data)))
    {
        std::cerr << "update error" << std::endl;
        return 0;
    }

    const char* key_context = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAh0UDlUA1aYPvfRFq6qUjDVG/fi5EetC6LsjdT/WNmHUAy0muvuOTFfQEzBoELciDfh23VXgwVnb/XsfuvQrCgtnQbuMKsj+sDhofLjeq8TznEMlQcJ//0LsGSM8rRVHw72BYA2mSVKi04k1GIicB9J25c2f+eIwF7lEWJlWqVDlNqOS7GIIjnq3HPhqki3ZRSA9c";

    EVP_PKEY* pub_key = EVP_PKEY_new();
    if(NULL == pub_key)
    {
        std::cerr << "evp_pkey new error" << std::endl;
        return 0;
    }

    // I have to call 'EVP_VerifyFinish' here!! but I don't know how to!!
    ERR_remove_state(0);
    ERR_free_strings();

    return 0;
}

請有人幫助我!

代碼未經測試,但是應該是這樣的:

BIO *mem= BIO_new(BIO_s_mem());
BIO_puts(mem, "your data");
RSA *cipher;
PEM_read_bio_RSAPublicKey(mem, &cipher, NULL, NULL);
EVP_PKEY *pkey  = EVP_PKEY_new();
EVP_PKEY_set1_RSA(pkey, cipher);

感謝您的回答..但是我做到了以下..((它可以找到..我已經測試過!!)

PS。 代碼中的Base64Decode功能。您可以在Internet上找到許多資源。

int Verify_GoogleInappBilling_Signature(const char* data, const char* signature, const char* pub_key_id)
{
    std::shared_ptr<EVP_MD_CTX> mdctx = std::shared_ptr<EVP_MD_CTX>(EVP_MD_CTX_create(), EVP_MD_CTX_destroy);
    const EVP_MD* md = EVP_get_digestbyname("SHA1");
    if(NULL == md)
    {
        return -1;
    }
    if(0 == EVP_VerifyInit_ex(mdctx.get(), md, NULL))
    {
        return -1;
    }

    if(0 == EVP_VerifyUpdate(mdctx.get(), (void*)data, strlen(data)))
    {
        return -1;
    }
//!!!!!!!!!!!!!!!!!!!
    std::shared_ptr<BIO> b64 = std::shared_ptr<BIO>(BIO_new(BIO_f_base64()), BIO_free);
    BIO_set_flags(b64.get(),BIO_FLAGS_BASE64_NO_NL);

    std::shared_ptr<BIO> bPubKey = std::shared_ptr<BIO>(BIO_new(BIO_s_mem()), BIO_free);
    BIO_puts(bPubKey.get(),pub_key_id);
    BIO_push(b64.get(), bPubKey.get());

    std::shared_ptr<EVP_PKEY> pubkey = std::shared_ptr<EVP_PKEY>(d2i_PUBKEY_bio(b64.get(), NULL), EVP_PKEY_free);
//!!!!!!!!!!!!!!!!!!!
    std::string decoded_signature = Base64Decode(std::string(signature));
    return EVP_VerifyFinal(mdctx.get(), (unsigned char*)decoded_signature.c_str(), decoded_signature.length(), pubkey.get());
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM