问题
In this RailsCast on PayPal it shows you how to encrypt a URL parameter before sending it to 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")
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
Suppose I was writing the code for PayPal's server. How would I decrypt this string? It appears to me that this code both public-key signs the string (to verify authenticity) and then encrypts the string (to provide privacy). What would the code be for doing the reverse, decrypting and verifying authenticity?
Thanks.
回答1:
Hi John here is an example of encryption / decryption using ruby openssl. Note its using AES for the cypher as DES3 seemed to be dropped in my version of ruby openssl. Calling gsub on the string to replace newlines seemed to break it so i have left it commented out. Hope it helps you out.
require 'openssl'
PAYPAL_CERT_PEM = File.read("paypal_cert.pem")
@paypal_cert = OpenSSL::X509::Certificate.new(PAYPAL_CERT_PEM)
APP_CERT_PEM = File.read("app_cert.pem")
@app_cert = OpenSSL::X509::Certificate.new(APP_CERT_PEM)
APP_KEY_PEM = File.read("app_key.pem")
@app_key = OpenSSL::PKey::RSA.new(APP_KEY_PEM, '')
PAYPAL_KEY_PEM = File.read("paypal_key.pem")
@paypal_key = OpenSSL::PKey::RSA.new(PAYPAL_KEY_PEM, '')
CERT_STORE = OpenSSL::X509::Store.new
CERT_STORE.add_cert(@app_cert)
data = Hash.new
data['customer_id'] = '123456789'
data['customer_name'] = 'Mr Smith'
def encrypt_for_paypal(values)
data_name_values = values.map { |k, v| "#{k}=#{v}" }
signed_data = OpenSSL::PKCS7::sign(@app_cert, @app_key, data_name_values.join("\n"), [], OpenSSL::PKCS7::BINARY)
cypher = OpenSSL::Cipher::new("AES-128-CFB")
encrypted_data = OpenSSL::PKCS7::encrypt([@paypal_cert], signed_data.to_der, cypher, OpenSSL::PKCS7::BINARY)
encrypted_data.to_s #.gsub("\n", "")
end
def decrypt_by_paypal(encrypted_data)
received_encrypted_data = OpenSSL::PKCS7.new(encrypted_data)
received_signed_data = received_encrypted_data.decrypt(@paypal_key, @paypal_cert)
p7_received_signed_data = OpenSSL::PKCS7.new(received_signed_data)
p7_received_signed_data.verify(nil, CERT_STORE, nil, OpenSSL::PKCS7::NOVERIFY)
p7_received_signed_data.data
end
encrypted_txt = encrypt_for_paypal data
puts decrypt_by_paypal encrypted_txt
来源:https://stackoverflow.com/questions/9062830/in-ruby-rails-how-to-decrypt-a-string-encrypted-and-signed-by-pkcs7