OpenSSL.NET 将 Ruby 示例移植到 C#(来自 RailsCasts 143 paypal-security)

发布于 2024-09-27 07:16:03 字数 756 浏览 6 评论 0原文

我正在关注有关 PayPal 安全性的 RailsCasts 剧集。我尝试将此代码移植到 C# 并使用 OpenSSL.NET

也可以这样做不使用 OpenSSL 包装器库,因为它使用一些非托管代码?

我尝试移植的 ruby​​ 代码是这样的:

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 包装器执行此操作?

I am following through the RailsCasts episode on PayPal security. I am try to port this code to C# and am using OpenSSL.NET

Also is it possible to do this without using the OpenSSL wrapper library as that uses some unmanaged code?

The ruby code that I am trying to port is this:

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

Does anyone know how to do this with C# OpenSSL wrapper?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

酒绊 2024-10-04 07:16:03

结果我发现了一篇文章解释了如何在 C# 中执行此操作。因此,请阅读并遵循该教程。我使用 Cygwin Bash Shell 来创建密钥。我已经包含了我使用的代码,因为它可能会有所帮助:)

这是书中发布的所有代码 专业 PayPal 电子商务 作者:Damon 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(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>

Turns out I found an article that explains how to do this for C#. So read an follow that tutorial. I used Cygwin Bash Shell to create the keys. I've included the code that I used as it may be helpful :)

This is all code that was published in the book Pro PayPal E-Commerce by Damon 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;
}

The FormEncryption class

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(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();
    }
}

Then the html form

<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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文