Paypal Integration with RoR application – Securing the transaction

This post is in continuation with the Post Paypal Integration with Rails Application – Integrating IPN. It is important that we secure our paypal transactions with some sort of encryption so that evil hackers dont find it a cakewalk to hack across the various parameters being sent to the paypal server. This step is completely optional but very much neccessary for the secure payments on our website. Generating a Key Pair The first step in securing the payments is to create a key that only our app understands. For this purpose, Create a directory named as ‘certs’ to accommodate certificates. Now generate an openssl keypair and RSA certificate using the following commands:
mkdir certs
cd certs
openssl genrsa -out app_key.pem 1024
openssl req -new -key app_key.pem -x509 -days 365 -out app_cert.pem
Now you have two files in certs directory. Login Merchant’s Account -> Options -> Encrypted Payment Settings -> Add -> browse and select app_cert.pem file -> Add. After you are done, you will see a column ‘Cert ID’ ,copy and paste (in some text file) the text under this column, its your paypal certificate id. We will use if in further steps. Select the added certificate (using radio buttton) and click Download button. Move the downloaded file to our certs directory created above. Modifying the application logic Now we need to modify the application logic to encrypt the parameters and propogate the neccessary certificate information to paypal to be able to decrypt the parameters at its end. In paypal_url method of app/models/product.rb, add :
cert_id => AppConfig.cert_id, after :notify_url => notify_url, replace :business => YOUR_MERCHANT_EMAIL with :business => AppConfig.paypal_email and replace

1 1="+" 2="values.to_query" 3="[/php" language="https://www.sandbox.paypal.com/cgi-bin/webscr?"]
with
encrypt_for_paypal(values)
24.Add following code to encrypt the information being sent to the paypal:
PAYPAL_CERT_PEM = File.read("#{Rails.root}/certs/paypal_cert.pem")
APP_CERT_PEM = File.read("#{Rails.root}/certs/app_cert.pem")
APP_KEY_PEM = File.read("#{Rails.root}/certs/app_key.pem")

# openssl encryption.
def encrypt_for_paypal(values)
signed = OpenSSL::PKCS7::sign(OpenSSL::X509::Certificate.new(APP_CERT_PEM),                                                         OpenSSL::PKey::RSA.new(APP_KEY_PEM, ''), values.map { |k, v|                                                                   "#{k}=#{v}" }.join("\n"), [], OpenSSL::PKCS7::BINARY)
OpenSSL::PKCS7::encrypt([OpenSSL::X509::Certificate.new(PAYPAL_CERT_PEM)],                                                        signed.to_der, OpenSSL::Cipher::Cipher::new("DES3"),                                                                                                                   OpenSSL::PKCS7::BINARY).to_s.gsub("\n", "")
end
Set the following values in your configuration file.
development:
paypal_url: "https://www.sandbox.paypal.com/cgi-bin/webscr"
paypal_email:  YOUR_MERCHANT_EMAIL
cert_id: PAYPAL_CERT_ID

production:
paypal_url: "https://www.paypal.com/cgi-bin/webscr"
paypal_email:  YOUR_MERCHANT_EMAIL
cert_id: PAYPAL_CERT_ID
Note:PAYPAL_CERT_ID is the certificate id that is saved above. In app/views/products/index.html.erb, replace
product.paypal_url(products_url)
with
product.paypal_url(products_url, notification_products_url)
Login to merchant account -> Profile -> Website Payment Preferences -> Select ‘ON’ radio button under heading ‘Encrypted Website Payments’ -> Save. It will block non-encrypted websites to make payments. That’s it. You are now sending encrypted parameters to paypal. Troubleshooting: uninitialized constant AppConfig : Please use whatever protocol you use to load environment specific configuration settings.
  • Pramod Shinde

    I followed all steps correctly, I am getting following error:

    Error DetectedError Message : We were unable to decrypt the certificate id.

    • Pramod Shinde

      My bad, I was downloading wrong certificate from PayPal, It worked when I downloaded and configured certificate under ‘PayPal Public Certificate’ section, insead of ‘Your Public Certificates’ section

      • Enbake

        Thanks for Sharing the info Pramod.