Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I verify Android In-app Billing with a server with Ruby?

I am having trouble figuring out how to verify Androind In-app Billing purchases with my Ruby on Rails server.

http://developer.android.com/guide/market/billing/billing_integrate.html

I think that Android gives a Security.java that has some sort of method to verify on physical device. From my research it seems like either (1) I need to figure out how to use this Security.java class with my Ruby on Rails server or (2) I need to port Security.java to Ruby.

Is this correct? Does anyone know another way to verify the receipt?

like image 608
slick28 Avatar asked May 11 '11 21:05

slick28


People also ask

What is in-app billing API?

The In-App Purchasing (IAP) API allows your app to present, process, and fulfill purchases of digital content and subscriptions within your app.


2 Answers

I just figured this out.

Basically the way it works is that when a purchase succeeds the android market sends back a message (formatted in JSON) with the order details and a cryptographic signature. In the Security.java class the verify function is making sure that the message really did come from the Android market application by verifying the signature using your public key.

If you want to use your own server in the mix, you simply need to pass the signature and json payload to your server and verify the json payload on your server. If you can verify that the json data came from the market application, you can use it to create your server side order objects. Then you can respond to your client application that the order was processed and update your UI.

What I did in my app is just add in the server communication stuff in the Security class' verify function in place of the existing verify function.

The real trick is writing signature verification code in ruby. Here's what works:

base64_encoded_public_key is your key in your user profile sig is the signature property being passed into the Dungeons security example data is the json string sent back by the market.

require 'rubygems'
require 'openssl'
require 'base64'

base64_encoded_public_key = "YOUR KEY HERE"
data = "JSON_DATA_HERE"
sig = "SIGNATURE HERE"

key = OpenSSL::PKey::RSA.new(Base64.decode64(base64_encoded_public_key))

verified = key.verify( OpenSSL::Digest::SHA1.new, Base64.decode64(sig), data )
like image 116
walta Avatar answered Oct 18 '22 06:10

walta


This worked for me only after double Base64 decoding of signature.

  public_key = Base64.decode64(public_key_b64)
  signature = Base64.decode64(Base64.decode64(signature_b64))
  signed_data = Base64.decode64(signed_data_b64)

  key = OpenSSL::PKey::RSA.new(public_key)
  verified = key.verify(OpenSSL::Digest::SHA1.new, signature, signed_data)
like image 41
kabochkov Avatar answered Oct 18 '22 07:10

kabochkov