В Ruby / Rails, как расшифровать строку, зашифрованную и подписанную PKCS7 - PullRequest
1 голос
/ 30 января 2012

В этот RailsCast на PayPal показывает, как зашифровать параметр URL перед его отправкой в ​​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

Предположим, я писал код для сервера PayPal.Как бы я расшифровал эту строку?Мне кажется, что этот код и открытый ключ подписывает строку (для проверки подлинности), а затем шифрует строку (для обеспечения конфиденциальности).Каким будет код для выполнения обратного, расшифровки и проверки подлинности?

Спасибо.

1 Ответ

1 голос
/ 05 февраля 2012

Привет, Джон, вот пример шифрования / дешифрования с использованием ruby ​​openssl. Обратите внимание, что он использует AES для шифра, так как DES3, похоже, пропущен в моей версии ruby ​​openssl. Вызов gsub в строке для замены символов новой строки, казалось, сломал ее, поэтому я оставил ее закомментированной. Надеюсь, это поможет вам.

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
...