This Hazel HZML/HTML page demonstrates my idea for a way to hide credit card numbers in plain sight. First, here's the demo part, with the discussion below.
Enter a test credit card number here:
To derive the original credit card number, multiply the first two digits of the card number by the last two digits of the client number, and use the six right-hand digits of that number. Subtract that result from the scrambled card number.
Decryption result:If you search the Hazel knowledge base, you will see there have been intermittent queries as to how best to encrypt the emails that Hazel uses to send credit card numbers. The consensus has been that the risk of sending the emails is very low, provided the email messages are stored on the same server where Hazel resides prior to being sent. The further consensus is that implementing an encryption program such as PGPSendmail or GnuPG is a hassle, there are limits to how a commercial operation can support PGP (though I take it GnuPG is a different story) and it's just not worth the trouble. There's also the issue of having to send half the email messages (the store invoices) encrypted while sending the other half (the messages to the customers) in clear.
For all of that, there is something unsettling about email messages with unprotected credit card numbers flitting hither and yon -- and maybe accumulating on the receiving computer. (And you likely want to retain those order emails for a while in case of problems with an order, etc.) If a bad guy managed to wander into your office with a 3.5 floppy and copied three months' worth of order emails off your hard drive -- well, that would be uncool. It might well be that keeping your credit card data secure on your own system was the bigger challenge.
Just yesterday, it struck me that the only thing that needs encryption is the credit card number itself. Furthermore, having that number off by a mere one digit ought to be enough to render it useless -- and would leave the bad guy wasting his time trying to get a useless number to work. (The system below actually scrambles four or five digits.) If the card number were scrambled just a trifle, and still looked like a legit number, and it were done in such a way that the original number would be easy to recover, that would be encryption enough. If the email were intercepted in transit, or stolen off your computer, the credit card number as shown wouldn't work.
I got the idea of using the credit card number itself, and/or other numbers sent in the store invoice, as a source of very basic encryption keys. The example above takes the first two digits of the credit card number and the last two digits of the client number and multiples them together. It then adds that result to the last six digits of the credit card number, and then prepends the first part of the credit card number to the addition result. It is in four sections, to accommodate card numbers of 13, 14, 15 or 16 digits.
(It would be more elegant to do one word loop, running it over each length and testing for the length, then doing the encrypt when the length matched, but that would require getting some pretty complex tags going. You'd not only have to drop the card length value into the regular expression that checked length, but also subtract six (I use the six digits on the right) from the card length value, and then plug that result into the fixed-length tag inside the value statement of the Hazel Vset that sets the value of HZV_scrambled_cred. I just couldn't figure out how to get a complex tag to do all that. Any suggestions?)
The idea is to do these calculations on the store invoice after Hazel has done her initial checks on the credit card number and has established that it is passes the CRC checks -- that is, that the number is valid format. Since the error-checking has already been done, it doesn't have to be done here. We can't get to this point in the process unless we have a properly formed card number. Once this very light encryption has been done, all that has to be done at the receiving end is to multiply the two values by each other and then subtract them from the reported card number to get the original card number. It would be duck soup to set up a little program, or a spreadsheet worksheet, into which the scrambled card number and the encryption keys could be cut-and-pasted, and which then would recover the original card number.
I am deliberately leaving one flaw in place here to make a point about selecting your keys carefully. By using the last two digits of the client number, I am leaving myself open to the one-in-a-hundred chance that the last digits will be 00, which, when multiplied by something else, will give the result of zero. When added to the credit card number, you'd get the number in clear. (Try it for yourself. Enter a bogus card number that starts with two zeros (impossible in real life) and you'll see the card number comes through unscrambled.) For this reason, it is probably wiser to use the leading rather than trailing digits of a number (because the first two digits won't be zero) and/or to add a fixed value to the final scrambler number before adding it to the card number. If you added three to whatever else the calculation came up with, you'd still have knocked the card number off by something, even if your previous additions and multiplications came up zero. A few other notes on the process:
(Note: I have deliberately omitted the leading % (percent sign) from the Hazel Tags in this paragraph so Hazel wouldn't actually try and present the values instead of the tag names.) What is shown here is a demo. In real life, you'd replace HZV_CREDTEST with HZE_CREDIT_CODE, and insert the calculation loops into your storeinvoice.txt template. Obviously, you would not display any of the interim values, but would merely show the results, formatted to make the card number look real. You'd remove the HZM_PAYMENT_INFO tag from your storeinvoice.txt template. That tag shows credit card info in this manner: "XXXXXXXXXXXXXXXX (type, expires XX/XXXX) issued to'cardholder name'." You would instead provide the information in the tags HZV_SCRAMBLED_CRED, HZE_CREDIT_MONTH, HZE_CREDIT_YEAR, HZE_CREDIT_TYPE, and HZE_CREDIT_NAME. Also just by the way, I used Hazel's fixed-width token feature to snag the bits of numbers. For a given variable HZx_Variant, (with x being any of the namespaces) HZx_nnR_Variant will show the last nn characters of the value of Variant. Use nnL to pick off digits from the front of the variable. For example, HZV_04L_Variant will show the first four characters of Variant. The number of digits must have a leading zero if it less than ten. See Fixed-Width Tokens in the Tokens section of the Hazel Online docs for more info.