[PYTHON-CRYPTO] credit card encryption

Paul Rubin phr-pycrypt at nightsong.com
Tue Jun 11 23:50:25 CEST 2002


    Both offer an implementation of RSA.  In the preliminary searching
    I've done on RSA, there seems to be an issue related to padding.
    The M2Crypto encrypt/decrypt methods have an option to specify a
    type of padding (e.g., pkcs1_padding).  amk's Crypto offers no
    such options.

    Do I have to worry about padding?

Yes, you have to worry about padding.  pkcs1 is sort of disfavored
these days but it should be ok for what you're doing.

    Simplistically, I would probably add a fixed amount of random
    information to the credit card number before encrypting it.  Is
    that sufficient?

No, don't do that.  RSA padding is a complicated subject and there's
been a flurry of academic papers about it in the past year or two.
For example, the original PKCS1 has been replaced with an "improved"
PKCS1 which was replaced with OAEP which is now deprecated in favor of
RSA-KEM.  Use a scheme that's already been vetted, even PKCS1 (which
has some theoretical weaknesses).

    The thing I'm most leery about is key management.  M2Crypto
    provides a way to protect the private key with a passphrase.
    amk's Crypto suggests using pickle to save the key(s).  I suppose
    I could use SHA to generate a key from a passphrase, and then use
    that key to symmetrically encrypt the private key data before I
    save it to a file.  Of course, how does the batch process for
    sending payment information to the payment processor get access to
    the private key?  I haven't resolved that issue.  Worst case
    scenario is the batch has to wait until someone types in the
    passphrase to unlock the private key.

It sounds to me like you're dealing with two different problems:

1) protecting the secret key on the web server--that's easy, don't
   have a secret key there.  That's presumably why you're using public
   key encryption.

2) Protecting the key on the separate server that talks to the payment
   processor.  Is that done over the internet?  Is it a manual process?
   The simplest approach is keep that server disconnected from the
   internet except when processing payments (I'm imagining a daily
   upload).  Unfortunately that means you can't do online card verification
   when the customer places the order (it's nice to tell them right
   away that their card was declined, because they entered the wrong
   zip code or something like that).  If you have to keep the payment
   server online, firewall it so that it can't talk to anything except
   the card processor and the web server.  Better yet, don't connect
   it to the web server by TCP/IP.  Connect it by serial port instead,
   to further lower the chance of anyone rooting the payment server
   by breaking through some TCP service.

The really hardcore way protect online secret keys is by generating
and storing them in a crypto hardware module.  See for example
www.ibutton.com (look at the java crypto ibuttons) for examples.
You're supposed to do this if you're processing a lot of transactions
or storing a lot of card numbers (like 100's of thousands).

I don't mean to be looking for opportunities to plug my own code but I
also have a library documented at

    http://www.nightsong.com/phr/python/crypto.txt

which is written in pure Python.  It currently doesn't support RSA,
but supports a public key scheme based on Diffie-Hellman key exchange
whose padding issues are hopefully simpler.  Its claim to fame is
running in a separate process from your application, so you can (for
example) start the cryptography ("server") process running and enter a
passphrase to unlock the secret key, then leave the process running so
the application can use the key in memory, but the key is never
written to disc.  You can also put the crypto server on a separate
computer and store your keys on the separate computer.  My intention
is to set up a Sharp Zaurus (Linux PDA) as a crypto coprocesor using
this library but I haven't gotten around to this yet.

The design of the library is inspired by the key management features
of crypto hardware modules.  The library is still unreleased and I
wouldn't advise using it for production in its current state, but if
you want to look at it and play with it, that's fine.  In any case,
its docs might give you some idea of how to deal with these issues.

I also don't mean to disparage M2 or AMK's libraries in the
least--they both look pretty good, I'm just not familiar in detail
with either of them.

Paul




More information about the python-crypto mailing list