PayPal Hacks. 100 Industrial-Strength Tips and Tools Free Open Book

PayPal Hacks. 100 Industrial-Strength Tips and Tools

Previous Section  < Day Day Up >  Next Section

Hack 37 Hack-Proof Your Buttons with Encryption

figs/expert.gif figs/hack37.gif

Add yet another layer of security to a Buy Now Button by encrypting its contents with OpenSSL and C/C++.

Now that you've created a complete Buy Now button [Hack #28], how can you prevent potential hackers from seeing (and possibly changing) the information you're passing to PayPal? PayPal's button encryption enables you to hide the exact contents of your HTML form in a PKCS7-encrypted blob.

While it is not necessary to integrate button encryption into every web site, it does allow you to provide another layer of security without affecting your customers' buying experience.

This hack shows how to secure the contents of a button using OpenSSL and C/C++. For a simpler solution, see [Hack #36] .


4.11.1 OpenSSL and Keys

Button encryption is done using a cryptography library, such as OpenSSL, and a pair of cryptographic keys. OpenSSL is nice, because it allows you to both sign and envelope the message in one action. The first thing to do is install OpenSSL, which is available for download at http://www.openssl.org.

Note that some knowledge of compiling programs is required for the installation of OpenSSL on Unix. Instructions for compiling and installation on various platforms can be found in the OpenSSL download. A precompiled Windows version is available at http://www.slproweb.com/products/Win32OpenSSL.html. Simply follow the installation instructions for your particular environment.

Cryptographic keys must be exchanged in order for button encryption to work. You'll need to contact PayPal to obtain PayPal's public key, and you must provide your public key to PayPal. You should generate your keys in PEM format; consult the OpenSSL documentation (http://www.openssl.org/docs/HOWTO/keys.txt) for details.

4.11.2 Basic Button Encryption Using OpenSSL

Start with an unencrypted HTML form tag in your HTML page:

<form method="post" action="https://www. paypal.com/cgi-bin/webscr">

<input type="hidden" name="cmd" value="_xclick">

<input type="hidden" name="business" value="sales@company.com">

<input type="hidden" name="amount" value="1.00">

<input type="hidden" name="currency_code" value="USD">

<input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but23.gif"

                name="submit" alt="Make payments with PayPal - it's fast, free 

                and secure!">

</form>

The first thing you need to do is convert all the hidden field name/value pairs from this form into a single string, like this:

cmd=_xclick

business=sales@company.com

amount=1.00

currency_code=USD

Keep in mind that the line feeds required are Unix line feeds (\n), not Windows line feeds (\r\n). Ensure that your program is creating the string correctly or you will get decryption errors when posting your encrypted form.


Next, load the PayPal public key from the paypal_cert.pem file:

BIO *bio;

X509 *gPPx509;

char* payPalCertPath = "/opt/keys/paypal_cert.pem";

if ((bio = BIO_new_file(payPalCertPath, "rt")) == NULL) {

        printf("Fatal Error: Failed to open (%s)\n", payPalCertPath);

        goto end;

}



if ((gPPx509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) == NULL) {

        printf("Fatal Error: Failed to read Paypal certificate from 

                (%s)\n", payPalCertPath);

        return "";

} 



BIO_free(bio);

Then, load your public and private keys:

X509 *x509 = NULL;

RSA *rsa = NULL;



char* certPath = "/opt/keys/my_cert.pem";

char* keyPath = "/opt/keys/my_key.pem";



if ((bio = BIO_new_file(certPath, "rt")) == NULL) {

        printf("Fatal Error: Failed to open (%s)\n", certPath);

        goto end;

}



if ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) == NULL) {

        printf("Fatal Error: Failed to read certificate from (%s)\n", certPath);

        goto end;

}



BIO_free(bio); 



if ((bio = BIO_new_file(keyPath, "rt")) == NULL) {

        printf("Fatal Error: Failed to open (%s)\n", keyPath);

        goto end;

}



if ((rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL)) == NULL) {

        printf("Fatal Error: Unable to read RSA key (%s).\n", keyPath);

        goto end;

}



BIO_free(bio);



' Create an EVP_PKEY instance from the private key you just loaded:

EVP_PKEY *pkey = EVP_PKEY_new( );



if (EVP_PKEY_set1_RSA(pkey, rsa) == 0) {

        printf("Fatal Error: Unable to create EVP_KEY from RSA key\n");

        goto end;

}



' create the PKCS7 instance so you can create the PKCS7 Blob:

PKCS7 *p7 = PKCS7_new( );                

PKCS7_set_type(p7, NID_pkcs7_signedAndEnveloped);



PKCS7_SIGNER_INFO* si = PKCS7_add_signature(p7, x509, pkey, EVP_sha1( ));



if (si) {

        if (PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, V_ASN1_OBJECT,

                                OBJ_nid2obj(NID_pkcs7_data)) <= 0) {

                printf("OpenSSL Error: %s\n", ERR_error_string(ERR_get_error( ), NULL));

                goto end;

        }

} else {

        printf("Fatal Error: Failed to sign PKCS7\n");

        goto end;

}



//Encryption

if (PKCS7_set_cipher(p7, EVP_des_ede3_cbc( )) <= 0) {

        printf("OpenSSL Error: %s\n", ERR_error_string(ERR_get_error( ), NULL));

        goto end;

}



if (PKCS7_add_recipient(p7, gPPx509) <= 0) {

        printf("OpenSSL Error: %s\n", ERR_error_string(ERR_get_error( ), NULL));

        goto end;

}



if (PKCS7_add_certificate(p7, x509) <= 0) {

        printf("OpenSSL Error: %s\n", ERR_error_string(ERR_get_error( ), NULL));

        goto end;

}



BIO *p7bio = PKCS7_dataInit(p7, NULL);



if (!p7bio) {

        printf("OpenSSL Error: %s\n", ERR_error_string(ERR_get_error( ), NULL));

        goto end;

}



//Pump data to special PKCS7 BIO. This encrypts and signs it.

BIO_write(p7bio, data, strlen(data));

BIO_flush(p7bio);

PKCS7_dataFinal(p7, p7bio);                



//Write PEM encoded PKCS7

BIO *bio = BIO_new(BIO_s_mem( ));



if (!bio || (PEM_write_bio_PKCS7(bio, p7) == 0)) {

        printf("Fatal Error: Failed to create PKCS7 PEM\n");

}



BIO_flush(bio);                



char *str;

int len = BIO_get_mem_data(bio, &str);



char *ret = new char [len + 1];

memcpy(ret, str, len);

ret[len] = 0;



' free the resources:

PKCS7_free(p7);

BIO_free_all(bio);

BIO_free_all(p7bio);

The last step to enable button encryption is to change the value of the cmd form tag to _s-xclick and add the PKCS7 blob as a form value of encrypted..

When you're done, you'll end up with something like this:

<form method="post" action="https://www.sandbox.paypal.com/cgi-bin/webscr">

<input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but23.gif" 

name="submit" alt="Make payments with PayPal - it's fast, free and secure!">

<input type="hidden" name="cmd" value="_s-xclick">

<input type="hidden" id="encrypted" name="encrypted" value="-----BEGIN PKCS7-----

MIIEvQYJKoZIhvcNAQcEoIIErjCCBKoCAQExggE0MIIBMAIBADCBmDCBkjELMAkG

A1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQw

EgYDVQQKEwtQYXlQYWwgSW5jLjEVMBMGA1UECxQMc3RhZ2UyX2NlcnRzMRMwEQYD

VQQDFApzdGFnZTJfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tAgEA

MA0GCSqGSIb3DQEBAQUABIGACgshgqbB147NFGZlK23kRLaQ3EkGnFmnRWn8euqN

Ecm12daiK57CaU/L36dhc4PtkigXI2TQ/alWglyerZkOhl+qb6ZRTqEq2+7fhvsB

T32Yph/usVQEj5j0njtFmo9smOyEJuHcNYY5bn3gUsiM6FxIZq8qRlI5W9yh7hTc

1/kxCzAJBgUrDgMCGgUAMGsGCSqGSIb3DQEHATAUBggqhkiG9w0DBwQINNLmCVHP

OUWASIMAdhSkOjW5qKb98fpT1yLCByYMjvE0U39fuG3pSOXv8tKzKEz3v1sKDUOR

PRy0ekPFI6nEdp+dDJLBy3acM3DGrHk7KdYSLqCCAdIwggHOMIIBN6ADAgECAgEC

MA0GCSqGSIb3DQEBBQUAMBExDzANBgNVBAMTBlBheXBhbDAeFw0wNDAzMjkyMTU3

NDdaFw0xNDAzMjcyMTU3NDdaMBExDzANBgNVBAMTBlBheXBhbDCBnzANBgkqhkiG

9w0BAQEFAAOBjQAwgYkCgYEArdX6/kaw/9JWyxedVUBf1hLQ0nE3Z8HZTOAb8tTj

tH3anE8lxoA84NBKgsnAfsWSivWZA149NcpNrVgk7aPiCpIlxxLD7dv30zSqrXUA

kzVZ3xDfxILN42Xe8JZiM7MieixlKL/2RlnqHv6RyfAJyXH7cMlbLQJCBR3g4XnF

7I0CAwEAAaM2MDQwDgYDVR0PAQH/BAQDAgGmMA8GA1UdEwEB/wQFMAMBAf8wEQYJ

YIZIAYb4QgEBBAQDAgIEMA0GCSqGSIb3DQEBBQUAA4GBAD0CbksayWCC0yqZSn3c

6J65Yvmi/KrObGX7EzHcB1N0/YbfYkisw5qvZnGUhMj00DL3cvNOnPxXNBIUdHT3

UF1O8MzLlv8fTAjnS8Zd83vZfSyi6TMSPJlXbx8p+P2IbRNKdQaIHz2tR6tCnUNC

JYYKim3Nkz48sk0/jGtjiJPVMYIBGzCCARcCAQEwFjARMQ8wDQYDVQQDEwZQYXlw

YWwCAQIwCQYFKw4DAhoFAKBdMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJ

KoZIhvcNAQkFMQ8XDTA0MDQyMjIxMDkyMVowIwYJKoZIhvcNAQkEMRYEFO1Oou9z

6VXvxn6wow7yZXlP6vqeMA0GCSqGSIb3DQEBAQUABIGAoNU5uAeD+pp2bROOfhHh

6oTPZDjhUvKLrhVaHmpHzz1aZTtIdqYcwZ6vEVai6fGG43hqoZYAh97xWDiwW9Ie

X/RtAzc38Yk2vch6ocPF8MjsEMVne3J9iy0rN6A0Cby5IgkKFrrYee9eWNIec/6d

3koVvLSCBZvZV+RFYCKhA/0=

-----END PKCS7-----

"> 

</form>

Obviously, this code is nearly impossible to decipher or tamper with, making it sufficiently obfuscated.

Michael Blanton

    Previous Section  < Day Day Up >  Next Section
    Index: [SYMBOL][A][B][C][D][E][F][G][H][I][J][L][M][N][O][P][Q][R][S][T][U][V][W][X][Y]


         Main Menu
    PayPal Hacks
    Table of Contents
    Copyright
    Credits
    Preface
    Chapter 1. Account Management
    Chapter 2. Making Payments
    Chapter 3. Selling with PayPal
    Chapter 4. Payment Buttons
    Introduction: Hacks #28-44
    Hack 28 Create a Buy Now Button
    Hack 29 Use a Custom Button Image
    Hack 30 Create a Purchase Button for Services
    Hack 31 Create an Auction Payment Button
    Hack 32 Provide Purchase Options with Drop-Down Listboxes
    Hack 33 Include More Than Two Option Fields
    Hack 34 Override Shipping and Handling Preferences
    Hack 35 Build Notification Tracking
    Hack 36 Hack-Proof Your Payment
    Hack 37 Hack-Proof Your Buttons with Encryption
    Hack 38 Include Payment Buttons in Email Messages
    Hack 39 Hide Your Email Address from Spammers
    Hack 40 Accept Donations
    Hack 41 PayPal-Enable Your Flash
    Hack 42 Get More Out of Dreamweaver and PayPal
    Hack 43 Provide Options with ASP.NET Web Controls
    Hack 44 Try Accepting Payments in a Bogus Currency
    Chapter 5. Storefronts and Shopping Carts
    Chapter 6. Managing Subscriptions
    Chapter 7. IPN and PDT
    Chapter 8. The PayPal Web Services API
    Colophon
    Index


    More Books
    PHP Hacks
    Processing Xml With Java - A Guide To Sax, Dom, Jdom, Jaxp, And Trax
    The Koran (Holy Qur'an)
    Macromedia Flash 8 Bible
    Search Engine Optimization for Dummies
    YouTube Traffic
    PHP 5 for Dummies
    Harry Potter and The Chamber of Secrets
    Harry Potter and the Sorcerer's Stone
    The Pilgrim's Progress
    Wireless Hacks
    Flash Hacks. 100 Industrial-Strength Tips & Tools
    PayPal Hacks. 100 Industrial-Strength Tips and Tools
    Amazon Hacks
    Pdf Hacks
    The Da Vinci Code
    Google Hacks
    The Holy Bible
    Windows XP For Dummies
    Harry Potter and the Half-Blood Prince
    Seo Book
    Upgrading and Repairing Networks
    Macromedia Dreamweaver 8 UNLEASHED
    Windows XP Annoyances
    Windows XP Hacks
    Microsoft Windows XP Power Toolkit
    Teach Yourself MS Office In 24Hours
    iPod & iTunes Missing Manual
    PC Hacks 100 Industrial-Strength Tips and Tools
    PC Overclocking, Optimization, and Tuning - 2th Edition
    PC Hardware In A Nutshell 3rd Edition
    PC Hardware in a Nutshell, 2nd Edition
    Upgrading and Repairing PCs
    Google for Dummies
    MySQL Cookbook
    Teach Yourself Macromedia Flash 8 In 24 Hours
    PHP CookBook
    Sams Teach Yourself JavaScript in 24 Hours
    PHP5 Manual
    Free Games Paper Airplanes
    500 Juegos Gratis 500 Giochi Gratis 500 Jeux Gratuits 500 Jogos Gratis 500 Kostenlose Spiele