In Ruby/Rails, how to decrypt a string encrypted and signed by PKCS7

心已入冬 提交于 2019-12-24 10:27:23

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!