Groups > Asp .Net > ASP.NET Tips and tricks > Paypal - Encrypted Website Payments (EWP) Solution




Paypal - Encrypted Website Payments (EWP) Solution

Paypal - Encrypted Website Payments (EWP) Solution
Sat, 22 Mar 2008 05:53:18 +000
Integrating encrypted paypal buttons is a pain! Hopefully this helps.

Basically it is a 4 stage process. I have put it together from postings on other
sites. None of this is my own work so I can't take credit for it but I'm putting
it all here in one place to hopefully save you time.

The code is provided AS IS. It works for me but it may not work for you. I offer
no guarantees and I am unable to offer any help with modifying it. I host my
applications at maximumasp.com so I can tell you this works on their VPS servers
(Gratuitous plug: Maximumasp are great and my refferal number is DSHD-6726).

The sites where I found this information are:
http://www.pdncommunity.com/pdn/board/message?board.id=ewp&thread.id=4
http://www.paypaldeveloper.com/pdn/board/message?board.id=ewp&message.id=373
&query.id=33453#M373
http://dotnetdiscussion.net/2008/02/27/aspnet-how-to-integrate-both-google-check
out-and-paypal-in-3-steps/
https://www.paypal.com/IntegrationCenter/ic_button-encryption.html#step2

 

The p12 certificate


Download and install Win32 OpenSSL from Shining Light Productions. Then Create a
private key: 
    openssl genrsa -out my-prvkey.pem 1024

Create a public cert using the private key:
    openssl req -new -key my-prvkey.pem -x509 -days 3650 -out my-pubcert.pem

Export the private key and public cert to PKCS#12 format:
    openssl pkcs12 -export -inkey my-prvkey.pem -in my-pubcert.pem -out
mycert.p12

You will be prompted for creating a password when you export to PKCS#12 format.
Remember the password. You will need the .p12 file and its password when you use
this class.

If you are on a shared virtual hosting plan, you may need to contact your
hosting company to get them to install the certificate on your server. Send them
the .p12 certificate and it's password.

Upload your certificate to your PayPal account to get your "cert_id"
for the code behind, download the PayPal certificate and put it in your App_Data
folder, then block non encrypted payments. All here:
https://www.paypal.com/IntegrationCenter/ic_button-encryption.html#step2

 

The Form

Add these variables between the form tags of your aspx page
<input type="hidden" name="cmd"
value="_s-xclick">
<asp:Literal runat="server" id="strEncrypt" />

Add an asp button with the postback url set to either the sandbox or live paypal
site
<asp:Button ID="btnPayPal" runat="server" Text="Pay
with PayPal"
PostBackUrl="https://www.sandbox.paypal.com/cgi-bin/webscr" />

 

The code behind

This encrypts your form variables and writes a hidden variable named
"encrypted" to the literal "strEncrypt". Put this where it
will be executed before the user can click "btnPayPal" (e.g.
Page_Load).

Add
Imports com.paypal.demoDim paypalCertPath AsString =
Server.MapPath("~/App_Data/paypal_cert_pem.txt")
Dim signerPfxPath AsString = Server.MapPath("~/App_Data/mycert.p12")
Dim signerPfxPassword AsString = "mycert.p12 password"'testing only -
get from secure place when live.
Dim clearText AsString = "cmd=_xclick" & vbLf & _
"business=you@yourbusiness.com" & vbLf & _
"currency_code=GBP" & vbLf & _
"item_name=Subscription" & vbLf & _
"amount=15.00" & vbLf & _
"no_shipping=2" & vbLf & _
"no_note=1" & vbLf & _
"return=https://www.yoursite.com/return.aspx" & vbLf & _
"cancel_return=https://www.yoursite.com/cancel.aspx" & vbLf &
_
"cert_id=C2XRTSNRF7E2S"
Dim ewp AsNew ButtonEncryption()
ewp.LoadSignerCredential(signerPfxPath, signerPfxPassword)
ewp.RecipientPublicCertPath = paypalCertPath
Dim result AsString = ewp.SignAndEncrypt(clearText)

strEncrypt.Text = "<input type=""hidden""
name=""encrypted"" value=""" & result
& """ />"


The class

This class has been slightly modified from PayPal_HarryX's original to prevent a
"System.Security.Cryptography.CryptographicException: The system cannot
find the file specified" error. It has also been converted to VB. You can
download the original C# version from PayPal_HarryX's post but you need to
change:

_signerCert = new X509Certificate2(signerPfxCertPath, signerPfxCertPassword);

to

_signerCert = new X509Certificate2(File.ReadAllBytes(signerPfxCertPath),
signerPfxCertPassword, X509KeyStorageFlags.MachineKeySet);

And add the namespaces
using system.IO
using System.Security.Cryptography.X509Certificates

Here is the original. And here is the fix.

Save this class in the App_Code folder of your application.

Here is the modified VB code.

Imports Microsoft.VisualBasic
Imports System
Imports System.Web
Imports System.Collections.Generic
Imports System.Text
Imports System.Security.Cryptography
Imports Pkcs = System.Security.Cryptography.Pkcs
Imports X509 = System.Security.Cryptography.X509Certificates
Imports System.Security.Cryptography.X509Certificates
Imports System.IONamespace com.paypal.demo

PublicClass ButtonEncryption
Private _encoding As Encoding = Encoding.[Default]
Private _recipientPublicCertPath AsString
Private _signerCert As X509.X509Certificate2
Private _recipientCert As X509.X509Certificate2PublicSubNew()

EndSub

#Region"Properties"
''' <summary>
''' Character encoding, e.g. UTF-8, Windows-1252
''' </summary>

PublicProperty Charset() AsString
Get
Return _encoding.WebName
EndGet
Set(ByVal value AsString)
If value IsNotNothingAndAlso value <> ""Then
_encoding = Encoding.GetEncoding(value)
EndIf
EndSet
EndProperty

''' <summary>
''' Path to the recipient's public certificate in PEM format
''' </summary>

PublicProperty RecipientPublicCertPath() AsString
Get
Return _recipientPublicCertPath
EndGet
Set(ByVal value AsString)
_recipientPublicCertPath = value
_recipientCert = New X509.X509Certificate2(_recipientPublicCertPath)
EndSet
EndProperty
#EndRegion

''' <summary>
''' 
''' </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>

PublicSub LoadSignerCredential(ByVal signerPfxCertPath AsString, ByVal
signerPfxCertPassword AsString)
Try
_signerCert = New X509.X509Certificate2(File.ReadAllBytes(signerPfxCertPath),
signerPfxCertPassword, X509KeyStorageFlags.MachineKeySet)
Catch ex As Exception
ThrowNew Exception("<b>Signer Cert Path: " &
signerPfxCertPath & "</b><br><br>" &
ex.ToString())
EndTry
EndSub

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

PublicFunction SignAndEncrypt(ByVal clearText AsString) AsString
Dim result AsString = Nothing
Dim messageBytes AsByte() = _encoding.GetBytes(clearText)
Dim signedBytes AsByte() = Sign(messageBytes)
Dim encryptedBytes AsByte() = Envelope(signedBytes)
result = Base64Encode(encryptedBytes)
Return result
EndFunction

PrivateFunction Sign(ByVal messageBytes AsByte()) AsByte()
Dim content AsNew Pkcs.ContentInfo(messageBytes)
Dim signed AsNew Pkcs.SignedCms(content)
Dim signer AsNew Pkcs.CmsSigner(_signerCert)
signed.ComputeSignature(signer)
Dim signedBytes AsByte() = signed.Encode()
Return signedBytes
EndFunction

PrivateFunction Envelope(ByVal contentBytes AsByte()) AsByte()
Dim content AsNew Pkcs.ContentInfo(contentBytes)
Dim envMsg AsNew Pkcs.EnvelopedCms(content)
Dim recipient AsNew
Pkcs.CmsRecipient(Pkcs.SubjectIdentifierType.IssuerAndSerialNumber,
_recipientCert)
envMsg.Encrypt(recipient)
Dim encryptedBytes AsByte() = envMsg.Encode()
Return encryptedBytes
EndFunction

PrivateFunction Base64Encode(ByVal encoded AsByte()) AsString
Const PKCS7_HEADER AsString = "-----BEGIN PKCS7-----"
Const PKCS7_FOOTER AsString = "-----END PKCS7-----"
Dim base64 AsString = Convert.ToBase64String(encoded)
Dim formatted AsNew StringBuilder()
formatted.Append(PKCS7_HEADER)
formatted.Append(base64)
formatted.Append(PKCS7_FOOTER)
Return formatted.ToString()
EndFunctionEndClass
EndNamespace



Good Luck!

If this post was helpful to you, Please "Mark As Answer".
Post Reply
about | contact