RSA implementation, please comment.

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

Threaded View
Hi All;
I've come up with a solution and I'd like some feedback on whether or
not it is secure.

SYNOPSIS: Is Crypt::RSA secure acceptable in open source if the
private key password is in a browser cookie?

We're running a pretty basic LAMPS system with MySQL 5.1 and Perl 5.8.
The client asked me to devise "a secure way to save credit card
numbers in the sales database".  Every paper I've read recommends
saving the card numbers off site or not at all, but in this case the
the client is a middle-man who collects the sales information
(including card numbers) in one place, and needs to pull up the entire
customer record including card data in a back-office setting using a
secure server.

Most encryption and decryption schemas I came up with had the same
problem -- open source.  Any method that would encrypt the data in
MySQL and be decrypted by Perl could be read if someone were to gain
access to the server.  The MySQL login script could also be read in
open source, so I feared that no matter how well we encrypted the
data, a hacker would only have to follow the script to gain access to
thousands of card numbers.

The staff members will be opening hundreds of orders per day, and they
need the encryption to be fast and transparent with no inconvenience
at all to the legitimate users.

Here is the solution I came up with:

1. Using  Crypt::RSA I created a 256 bit public and private key with a
63 character password. Both keys are saved on the server, but the
password is not.
2. The credit card number is a blob field.  When a new order is
entered, it is encrypted with the public key and saved.
3. Authorized users will use a JavaScript page to set a cookie with
the private key's password. It will be a session only cookie, which is
removed automatically when the user logs out of the database
4. If the cookie is present, the script will use its value to open the
private key and display the card info. Otherwise, it only displays

I believe that this solution is secure because the private key
password is never saved on the server. A hacker would have to gain
access to an authorized user's PC to gain the password.  I am not sure
how difficult it is to crack a 256 bit private key with a 63 character
pass. There is plenty of documentation on how hard it is to brute
force the entire key, but not much I could find on the password.

If you can see a security hole with this method, please reply.

Re: RSA implementation, please comment.

Rob wrote:
Quoted text here. Click to load it

  I don't know if I can talk you out of keeping the card numbers on the
same server but I'm going to try. A dedicated server can be leased for a
hundred dollars a month. There is no legitimate excuse for keeping the
numbers on a server which is accessible by a web browser. Servers are
compromised despite the best intentions of the server admins. If the web
server were ever compromised it could be a disaster for your client. The
256 bit RSA key could be factored in hours. You would need a much larger
key for it to be secure.

  If you must store the data on the same web server, then you are better
off generating an encryption key from a good quality random number
generator and using a two way algorithm like RC4 (very fast encryption,
BTW). The random number generator will return the same string if the
seed is the same. You will get the seed from a hash of a concatenation
of the username, email address, phone number, user's password (you will
have in in plain text from the form, but store encrypted or hashed),
etc. Cat all those strings in any order you want, pass it through SHA512
or somesuch, and pass the resulting string to your RNG. Poof, out comes
your password, for that user only.

Don't store the expiration or CCV/CCV2.


Re: RSA implementation, please comment.

On Tue, 01 Jul 2008 18:20:51 -0700, -linux_lad wrote:

Quoted text here. Click to load it

RC4 has serious security issues, see Wikipedia for more information on


Re: RSA implementation, please comment.

On Tue, 01 Jul 2008 17:24:08 -0700, Rob wrote:

Quoted text here. Click to load it

Besides not being terribly secure, but also not terribly insecure, I see
one fatal flaw in your plan. How is the client going to use the private
key? As I read it, you are going to use javascript. I think you'll find
that opening the key will take forever and using it even longer.

Replace the client side with a Java applet or application and the whole
thing becomes much more viable.


[OT] Re: RSA implementation, please comment.

[ This has nothing to do with Perl. If you want to continue the
conversation, find an appropriate group or take it to mail ]

On Tue, 01 Jul 2008 17:24:08 -0700, Rob wrote:

Although I'll try to improve on your security, you'ld best take a step
back and look at the whole problem again. Storing the creditcard details
on a separate server is actually a very good idea, because a server with
less functions is easier to secure.

So set up a web front. This web front uses a well defined and secure
channel to talk to the credit-card-details server. This must go through a
firewall that allows nothing else from web front to credit-card-details

The protocol should be custom defined, well implemented by someone used
to secure coding and only allow storing the details, not deleting,
altering or retrieving them (some retrieval may be necessary, but never
the card number). If alteration is a must, this must be very carefully
implemented, probably by sending a new card record and storing a link to
the new record, not deleting the old record. Avoid the temptation to use
a raw database connection. Even when the database itself is properly
secured (which it should be), you take away one layer of defense and rely
on the database security alone, which is notoriously hard to get right.

The clients use well defined and secure channels to talk to this server.
Start with allowing only access from specific IPs. Using certificates on
smart cards is a common way to further secure this access. Also pay
attention to administrative access, this should be even more secure.

Only with this setup you can be reasonably secure. Public webservers get
hacked way more often than dedicated servers, by splitting your
functionality between a public webserver and a dedicated backend server
you can avoid damage when your webserver gets hacked.

And pay attention to backup! The number of times I've seen setups like
the above, all computers secured, behind a dedicated firewall, all
perfectly according to the book, only to find that the backup network
ties them all together again without a firewall in sight.

If you have all the above right, you can start implementing details.

Quoted text here. Click to load it

Brute forcing a 63 character password is doable, although very time
consuming. For most e-commerce, I would say it's acceptable if there is
no other solution.

But are your users really going to enter a 63 character password? If no,
the password is shorter and easily brute forced. If yes, users will store
the password which can be regained by an attacker.

Here's an alternative.

- Don't store the private key on the server. Use the public key to
encrypt the card details.

- Every client gets a smartcard for the decryption (or a HSM, but those
are costly).

- Use a pin to protect the smartcard (commonly called a pin in the
context of smartcards, but often can actually be a pass phrase)
(actually, you use a pin to protect specific items on the card)

- Store the private key only on the smartcard. Make sure the key can only
be used for decryption and cannot be retrieved.

- Use an application client side to drive the smartcard (can be a Java

With this scheme, an attacker can crack the server, but cannot get at the
credit card details.

Why is this more secure?
- Private key gets only stored in smartcard, so -- if properly implemented
[2] -- impossible to copy.
- Brute forcing smartcard PINs is -- if properly implemented --
impossible. The card locks up after a number of wrong guesses.
- Man in the middle attacks are impossible.
- hacking the client computer does not immediately give an attacker full
access, he still needs a smartcard (if client is hacked, consider the PIN

But this scheme has an obvious weakness. If a smartcard gets stolen,
together with the PIN, your borked. To get around that:

- If a smartcard gets missing/stolen, it must be reported immediately.
Draw up a contract that says the holder is responsible for damages
occurring through misuse of their card.

- Use a certificate per smartcard.

- The certificate gets stored on the server, together with a status flag
(inactive, active, stolen, revoked) (ldap is very good at storing

- The private for the certificate key is stored on the smartcard,
protected by pin.

- This certificate is used to identify the client, so they don't have to
log on using user name+password (side effect, but makes it much more
useable for the client). Most (all?) webservers can do this very easily
and most (all?) webbrowsers support this.

- The certificate and private key are used to generate a session key. If
properly implemented, only the server and the smartcard know this key.
The client software doesn't know this key at all. However, you might want
to compromise here a bit.

- The encrypted credit card details are encrypted again by the server
with the session key and send to the client.

- The client uses the smartcard to decrypt the encrypted-encrypted credit
card details, then uses the smartcard again to decrypt the encrypted

Why is this more secure than my first scenario?
- If a smartcard+PIN gets stolen, you have a fighting chance to revoke
the certificate before it is used.

However, this still leaves the attacker the possibility to crack the
server, get the single-encrypted details and use a stolen smartcard+pin
to decrypt the data. So the scheme should be enhanced:

- Protect the common private key not only by pin, but also by another
mechanism. The cards certificate should be presented to an authentication
server[1] (not the same server as the one storing the creditcard details)
which gives back a key (unique for that card) that can be used to unlock
the common private key. If you implement this you can even drop the pin
protecting the common private key.

Now an attacker has to hack two servers, and steal a smartcard+PIN.
(Aside from doing a lot of work once he has these).

[ Disclaimer, only thinking about this for an hour makes the above
suspect. I may very well have overlooked something, in fact I probably
have. I just want to give directions, but you have to learn to swim
yourself. ]

There is another scheme, less secure, but easier implemented.

- Again, use another authentication server. Use certificates for clients
to log into this server and set up a secure communication channel.

- The common private key is stored on this authentication server and send
to the client over this secured channel.

- Client uses private key to access credit card details.


[1] Authentication servers are easier to secure, but they should be very
secure. Use a dedicated server, behind a dedicated firewall. Pay
attention to physical access.

If you need to administer remotely: use a public/private key pair to
grant access, preferably using smartcards, and only from certain IPs.

[2] "If properly implemented" is actually quite hard to ascertain. Never
assume, test, test, test. Build specific testframeworks[3] to be sure.
Assumption is the mother....

[3] I once replaced the Windows smartcard DLL to see what went on under
the hood. Found one bit that was wrong, which made the whole security of
that application worthless. Luckily this was in the security testing
stage, so it could be rectified before deployment.

Site Timeline