Monthly Archives: November 2010

An idea for improving credit card security

It seems like there’s always some company or other letting its credit card database fall into the hands of a malicious party, whether it’s internal or through the Internet. It’s obvious that people don’t know what they’re doing when it comes to taking necessary precautions to protect their data, and that they’re really good at storing it in plain text, which makes it simple to index.

What if it were possible for the model to shift in a manner that both introduced multi-factor protection on data and lets the clueless keep doing business without needing to learn anything new or change their processes at all (particularly that plain-text thing, since it’s so efficient)?

What I’d suggest is really quite simple: don’t store credit card numbers anywhere. At all.

Now, of course, the first response I’d expect to hear, were I to stop there, is “but we can’t take a hash and reconstruct a value understood by the processors, and encryption still involves storing the number!”, and whoever were to say that would be entirely right. The next thing I’d expect to hear is “but if we do away with credit card numbers, users won’t know how to pay for things!”, and this, too, is right.

Credit cards wouldn’t have to go away or change form at all. Numbers would still be transmitted over the Internet, covered by whatever transport-layer security is deemed acceptable by the involved parties, but something magical would happen when they’re received: they’d be sent to the credit card company, just as they are now. Shocking revolutionary twist, isn’t it?

No, it’s not quite that simple, but it’s pretty close. The credit card number would be sent along with a credit-card-company-issued merchant-ID and a unique identifier would be sent back, forever marrying the customer’s payment method with the merchant (no cryptographic integrity needed — it can be a predictable, sequentially-issued number, so long as it draws from a universal, multi-merchant-accessible pool to let entropy do its thing to prevent systematic lookups). Upon receipt of this identifier, the credit card number would be discarded and the identifier could be stored as an attribute of the user’s account on the merchant’s end. When the user wants to make another purchase, the identifier gets sent to the credit card company again and the onus is solely on that party (which should have nigh-impenetrable security) to figure out which financial institution’s patron to charge for the transaction.

“Okay, so… uh… what if the identifier gets compromised?”, I imagine to be the looming question to be. The answer is elegant in its absolutism: nothing.

The identifier uniquely identifies a pair of entities: the customer and the merchant. If the credit card company receives an identifier from a party other than the merchant to which it is registered, the transaction is void (and easy to stop, through an immediate severance of the binding) and if the merchant attempts to act fraudulently, the customer has a very clear path of recourse. Consumer-protection failsafes notwithstanding, the only circumstances under which an attack would be profitable to a malicious party would be if the merchant provided goods or services they cared about, and for that vector to be exposed, the attacker would need to have inside knowledge of how data actually flows between components of the merchant’s architecture, which would require the compromise of many disparate systems, providing multi-factor protection through the omnipresent mashup of security-oriented design and brain-breaking “MAKE IT WORK NOW” kludges.

To summarise this idea, a single sufficiently large numeric identifier (probably 1024-bit to start, which allows potential for easy expansion and eternal backwards-compatibility) would identify a customer (credit card) and a merchant (registered business) in a manner intelligible only to the credit card provider, the party with the greatest investment in security. This identifier could be stored unencrypted in databases and be protected by processes and checks, rather than arms-race-oriented encryption and social trust.

The fact that this identifier is bound to exactly one relationship means that its external value is non-existent and that its potential for harm, should it slip, is limited to that one relationship, making it something that can be treated as an attribute of another pre-existing parallel relationship (the user’s account with the merchant — though one-offs are fine, too, if the merchant doesn’t need to request an identifier), which allows whatever security resources a merchant has to be focused on protecting user data in general, for the company’s benefit, rather than the patron’s. (Authentication like Amazon’s or that of reputable banks would be a beneficial, but unnecessary, complement)

Lastly, the way that the identifier is known to only two parties (the merchant and the credit card company) means that it can be quickly abandoned (from the merchant’s end) if it ever gets compromised, without having any more impact than requiring a new identifier to be issued in a subsequent transaction.

Just a thought, though. Feel free to cite this to help overturn any patents that may be issued around a similar idea — security shouldn’t be encumbered.
Seems Moneris has been doing something similar for a while. Oh, well. At least the idea’s been implemented in some capacity.

Hymmnoserver updates underway

I recently received user-e-mail letting me know that I’ve fallen behind (again) in my goal of matching the Japanese Hymmnoserver’s content.

So, like, thanks for the heads-up, Maverynthia; I’ll get started on translating the new content and performing a vocabulary audit today, with hopes of finishing the process by next weekend.

Update: It looks like aquagon beat me to translating key technical details from new sections, so I’ll be using his work as a basis for my own. This should speed things up considerably.

staticDHCPd 1.6.x planned

Once the 1.5.x expansions are done, 1.6.x will be built, featuring a semi-stateful view into address-assignment, through a simple table design: the IP/subnet/serial key assigned to a MAC will be grouped with an expiration timestamp, allowing for an unreliable view of which hosts currently have “leases” (hosts that simply asked for configuration data, without an IP, will be tracked, too, with a special typecode). For DHCPv4 clients, this will be largely informational, enabling only the addition of LEASEQUERY support, but when v2 is implemented for DHCPv6, it will allow for server-initiated RECONFIGURE events, as described in section 19 of RFC 3315, which are pretty important, given the nature of the networks staticDHCPd is intended to serve.

This new subsystem will be configurable, using options like enable_leasequery and enable_reconfigure; if not enabled, the corresponding tracking mechanisms will not be used, for performance reasons. The data will also be storable in a local SQLite database, instead of the standard storage (this also allows for a second database if using SQLite already, to allow for better thread concurrency), to avoid a second remote access hit, when speed really matters.

While on the subject of performance, non-crucial data, like the list of clients remaining to be reconfigured and temporarily blacklisted MACs, may be stored in an in-memory SQLite database, rather than Python data-structures: this should save memory at a slight cost of speed; tests and stats will be necessary to decide whether the trade-off is worthwhile, though.

More enhancements planned for staticDHCPd 1.x

Although 1.5.0 will be published as previously described, I’ll continue extending it through 1.5.x, which will involve a revised logging engine, favouring deferred unattended writes to disk (to simplify forensics without impacting performance), a prettier web interface (though the information presented will remain about the same), and a few more runtime config options, including, if feasible, the ability to reload config options on the fly.

staticDHCPd, now with more activity

I’ve received a request to add DHCPv6 support to staticDHCPd. Lacking any reason to say no, I said yes, so v2 won’t be about moving to Python 3.0 (though I expect that the code will branch quite soon after this addition is complete), but rather about adding IPv6 support for those of you who actually need it.

My first step will be to finally add native PostgreSQL support, using psycopg, since it seems to have emerged as the dominant library since the last time I looked. This will finish 1.5.0 and mark the end of the 1.x line, save for any necessary bugfixes.

DHCPv6 support will be introduced by forking libpydhcpserver (the library that evolved from Mathieu Ignacio’s pydhcplib) into libpydhcpserver6, which may or may not be a full rewrite (if it can inherit from the old codebase, it will, but chances are it can’t, due to fundamental differences between option encodings and packet structure). Both libraries will be present in the new product, and IPv4 support will work alongside IPv6 support in the same process, to the fullest extent possible.

If anyone can recommend consumer-grade hardware that runs IPv6 (home routers, for example), I’d appreciate it, since all I’ll have to test with will be ISC-based VMs, due to a lack of physical routing fabric. (I’d like my tests to be as representative of reality as possible)

Creating a scripting language: branching out

While the language being developed was originally conceived of for work, I’ve realized that it can be easily adapted as a control language for a not-yet-ready-to-disclose game-related project I’m working on.

As such, it’s been given the name “prismscript”, and development will likely proceed under that title, and in that direction. (Since it’ll have more contributors and exposure that way, which should help to keep it healthy)