bytedreamer / Aporta

Aporta is an open source physical access controller. The main purpose of the software is to secure doors from unauthorized access. This is accomplished by determining if a person is authorized to enter a door. The door is unlocked momentarily by the software when authorized credential are presented.
Eclipse Public License 2.0
53 stars 6 forks source link

Suggestion: Don't hash the card numbers #4

Closed mistial-dev closed 1 year ago

mistial-dev commented 3 years ago

Hello,

Hashing the card numbers doesn't help with security, and makes card issuance and management harder.

With standard Wiegand cards (for example), there's generally a 26 bit ID. 8 bits are for the facility code (shared with the cards at the facility), the card number is 16 bits, and there are two parity bits.

Even if we assume that the whole 24 bits are for the card ID, we're still talking 16,777,216 possibilities total. Running a benchmark on the laptop I'm currently using with 1000 iterations, I get over 440kHash/s:

Hashmode: 12100 - PBKDF2-HMAC-SHA512 (Iterations: 999)

Speed.#2.........:   444.3 kH/s (85.72ms) @ Accel:4 Loops:249 Thr:1024 Vec:1

In other words, on this laptop, an exhaustive search of the keyspace should take around 380 seconds. Throw a decent GPU at it, and that number goes well under a minute.

Higher security with PACS cards comes generally not from the uniqueness of the ID (which is designed to be random enough to be difficult to brute force), but from having keys in the reader and keys in the card. The goal is to make the card un-dumpable and un-cloneable, rather than making it un-guessable. Even if the ID is extracted from the control panel, it can't be written to a card, unless one extracts the reader master keys.

bytedreamer commented 3 years ago

The purpose is to find a way to improve the security of the storage of card numbers. I agree the current implementation doesn't provide bulletproof security. There are few points that should be considered.

Thanks for the insights, let me know if you can come up with a better way of securing the card numbers.

mistial-dev commented 1 year ago

One goal is to get away from manually entering card numbers into the PACS. I don't believe having facility codes and card number bit ranges make any sense these days. Ideally, it should be a random 128 bit number that has no special meaning.

Almost nothing accepts 128 bit wiegand, though there are exceptions. The government standards for PIV (after validation) have a few different ways to do it.

The PIVClass PAM from HID offers a 40 bit option, a 64-bit option, a 75 bit option, 128 bit and 200 bits.

Looking at the HID Mercury LP1502 controller (a very popular one), the panel has support for 64-bit cardholders with 15 digit PINs.

https://www.hidglobal.com/doclib/files/resource_files/hid-mercury-lp1502-ds-en.pdf

HID has a format that I use when ordering credentials, and that's H10302. It's a 37-bit tracked format , which means that HID makes sure they never issue duplicates to anyone. Ignoring parity, it comes out to basically 34,359,738,368 possibilities.

On the high end in terms of bits, there's their 48-bit corporate 1000 program. It's supported in most hardware from what I can see, but beyond that compatibility seems to drop significantly.

Is your concern a hacker getting in and getting access to the database?

mistial-dev commented 1 year ago

Thinking about secure storage of wiegand data at rest, it's going to continue to be game over if the data itself is intercepted with most credentials.

Nonetheless, there is value in protecting at rest. It's necessary to be able to determine if a specified card is present in the allowed list, as well as handling a prohibitively long list of credentials.

Perhaps it would make sense to just encrypt the database.

SQLite supports encrypted databases. The key is stored in RAM (making extraction potentially possible), but it covers at rest, and it allows for quick searches, as well as export for backup purposes while remaining encrypted on the device itself.

With a PKCS11 interface (like the one mentioned in the other issue), it would be possible for the HSM to store a master key in one of its slots, then use it to decrypt a stored sqlite database password. The device could use this with the token to open the database at any time, provided the token supported the correct operations and key types.

This would also allow a plaintext version of the database key to be exported for backup purposes, and wrapped with a new token in the event the hardware needs to be replaced, or the device upgraded.

bytedreamer commented 1 year ago

The hashing of card numbers has been removed