2013-11-01 10 views
1

定公鑰我縮進在服務器端實現C或C++Initailzing EVP_PKEY(在OPENSSSL)從「谷歌應用程式內計費」

驗證「谷歌應用程式內計費簽名」我找到了方式,通過PHP(Android in-app billing signature verification in php server) 和建議它可以在openssl..but 使用EVP_Verify ...功能使用:

INT EVP_VerifyFinal(EVP_MD_CTX * CTX,無符號字符* sigbuf,無符號整型siglen,EVP_PKEY * p鍵);

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

我相信有方法將'Google InApp帳單簽名字符串(Base64編碼的SHA1與RAS簽名與PKCS#1填充)'轉換爲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; 
} 

請有人幫助我!

回答

0

謝謝回答.. ,但我做到了像下面.. (它的工作原理find..I've測試!!)

ps。 Base64Decode功能的代碼..你可能會發現在互聯網上有很多來源..

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()); 
} 
1

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

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); 
相關問題