2010-10-12 4 views
2

Я следую через RailsCasts episode по безопасности PayPal. Я пытаюсь перенести этот код на C# и использую OpenSSL.NETOpenSSL.NET Портирование примера Ruby на C# (из RailsCasts 143 paypal-security)

Также можно сделать это без использования библиотеки обложек OpenSSL, поскольку это использует какой-то неуправляемый код?

рубин код, который я пытаюсь порт это:

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 

Кто-нибудь знает, как сделать это с помощью C# OpenSSL обертке?

ответ

1

Оказалось, что я нашел article that explains how to do this for C#. Поэтому прочитайте этот учебник. Я использовал Cygwin Bash Shell для создания ключей. Я включил код, который я использовал, как это может быть полезно :)

Это весь код, который был опубликован в книге Pro PayPal E-Commerce Дэймоном Williams

private string EncryptForPayPal() 
{ 
    var Server = HttpContext.Current.Server; 

    string paypalCertPath = Server.MapPath("App_Data/paypal_cert_pem.txt"); 
    string signerPfxPath = Server.MapPath("App_Data/my_pkcs12.p12"); 

    string signerPfxPassword = "your_password_used_when_generating_keys"; 

    string clearText = "cmd=_xclick\n" + 
         "[email protected]\n" + 
         "currency_code=GBP\n" + 
         "item_name=Tennis Balls ßü (£12 umlot OK)\n" + 
         "amount=15.00\n" + 
         "return=https://localhost:2416/return\n" + 
         "cancel_return=https://localhost:2416/cancel\n" + 
         "cert_id=ZSGYTRNCK445J"; 

    FormEncryption ewp = new FormEncryption(); 
    ewp.LoadSignerCredential(signerPfxPath, signerPfxPassword); 
    ewp.RecipientPublicCertPath = paypalCertPath; 

    string result = ewp.SignAndEncrypt(clearText); 
    return result; 
} 

Класс FormEncryption

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Security.Cryptography; 
using Pkcs = System.Security.Cryptography.Pkcs; 
using X509 = System.Security.Cryptography.X509Certificates; 

public class FormEncryption 
{ 
    private Encoding _encoding = Encoding.Default; 
    private string _recipientPublicCertPath; 

    private X509.X509Certificate2 _signerCert; 
    private X509.X509Certificate2 _recipientCert; 

    /// <summary> 
    /// Character encoding, e.g. UTF-8, Windows-1252 
    /// </summary> 
    public string Charset 
    { 
     get { return _encoding.WebName; } 
     set 
     { 
      if (!string.IsNullOrEmpty(value)) 
      { 
       _encoding = Encoding.GetEncoding(value); 
      } 
     } 
    } 

    /// <summary> 
    /// Path to the recipient's public certificate in PEM format 
    /// </summary> 
    public string RecipientPublicCertPath 
    { 
     get { return _recipientPublicCertPath; } 
     set 
     { 
      _recipientPublicCertPath = value; 
      _recipientCert = new X509.X509Certificate2(_recipientPublicCertPath); 
     } 
    } 

    /// <summary> 
    /// Loads the PKCS12 file which contains the public certificate 
    /// and private key of the signer 
    /// </summary> 
    /// <param name="signerPfxCertPath"> 
    /// File path to the signer's public certificate plus private key 
    /// in PKCS#12 format</param> 
    /// <param name="signerPfxCertPassword"> 
    /// Password for signer's private key</param> 
    public void LoadSignerCredential(string signerPfxCertPath, string signerPfxCertPassword) 
    { 
     _signerCert = new X509.X509Certificate2(signerPfxCertPath, signerPfxCertPassword); 
    } 

    /// <summary> 
    /// Sign a message and encrypt it for the recipient. 
    /// </summary> 
    /// <param name="clearText">Name value pairs 
    /// must be separated by \n (vbLf or chr&#40;10)), 
    /// for example "cmd=_xclick\nbusiness=..."</param> 
    /// <returns></returns> 
    public string SignAndEncrypt(string clearText) 
    { 
     string result = null; 

     byte[] messageBytes = _encoding.GetBytes(clearText); 
     byte[] signedBytes = Sign(messageBytes); 
     byte[] encryptedBytes = Envelope(signedBytes); 

     result = Base64Encode(encryptedBytes); 

     return result; 
    } 

    private byte[] Sign(byte[] messageBytes) 
    { 
     Pkcs.ContentInfo content = new Pkcs.ContentInfo(messageBytes); 
     Pkcs.SignedCms signed = new Pkcs.SignedCms(content); 
     Pkcs.CmsSigner signer = new Pkcs.CmsSigner(_signerCert); 
     signed.ComputeSignature(signer); 
     byte[] signedBytes = signed.Encode(); 

     return signedBytes; 
    } 

    private byte[] Envelope(byte[] contentBytes) 
    { 
     Pkcs.ContentInfo content = new Pkcs.ContentInfo(contentBytes); 
     Pkcs.EnvelopedCms envMsg = new Pkcs.EnvelopedCms(content); 
     Pkcs.CmsRecipient recipient = new Pkcs.CmsRecipient(Pkcs.SubjectIdentifierType.IssuerAndSerialNumber, _recipientCert); 
     envMsg.Encrypt(recipient); 
     byte[] encryptedBytes = envMsg.Encode(); 

     return encryptedBytes; 
    } 

    private string Base64Encode(byte[] encoded) 
    { 
     const string PKCS7_HEADER = "-----BEGIN PKCS7-----"; 
     const string PKCS7_FOOTER = "-----END PKCS7-----"; 

     string base64 = Convert.ToBase64String(encoded); 
     StringBuilder formatted = new StringBuilder(); 
     formatted.Append(PKCS7_HEADER); 
     formatted.Append(base64); 
     formatted.Append(PKCS7_FOOTER); 

     return formatted.ToString(); 
    } 
} 

Затем html-форма

<form action="https://www.sandbox.paypal.com/cgi-bin/webscr"> 
    <%= Html.Hidden("cmd", "_s-xclick") %> 
    <%= Html.Hidden("encrypted", cart.PayPalEncypted(returnUrl, instantNotificationurl)) %> 
    <input type="submit" name="Checkout" value="Checkout" /> 
</form> 

 Смежные вопросы

  • Нет связанных вопросов^_^