Prototype private key hashing agent
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
LICENSE
README.md
rehash.go

README.md

Rehash

Rehash is a prototype agent for performing separate keyed hashes for memorized secret verification. The use of a separate, secret key in hashing makes it impractical for attackers to dictionary attack memorized secrets so long as the key remains a secret.

Rehash demonstrates one way of satisfying the recommendation in NIST Special Publication 800-63B that memorized secret verifiers “perform an additional iteration of a key derivation function using a salt value that is secret and known only to the verifier” (Section 5.1.1.2, last paragraph). While this might be done using a hardware security module (HSM) or similar device, it could also be done by a small, separate, appropriately-protected web service such as this.

Rehash uses the PBKDF2 key derivation algorithm described in NIST Special Publication 800-132 with the SHA-256 hash function as its underlying hash function. Accordingly, the input, output, and private key used by rehash are all 256 bits in length.

Installation

In normal use, rehash has very modest requirements: it is called once each time a password is verified (successfully or unsuccessfully) and when a password is changed. Depending on the throughput requirements of the verifier(s) it is serving, it could run on a processor as small as a Raspberry Pi.

Rehash is normally invoked at initialization time by an appropriate init script (operating system dependent). It accesses a single file, /etc/rehash.key, which contains the private key used by the hash.

The key stored in /etc/rehash.key is stored as a string of 64 hexadecimal digits. Many different processes can be used to generate the private key; it is essential that the key not be guessable by an attacker so a string of 256 bits generated by a suitable random number generator be used. A backup copy of the key, stored offline, should be maintained to provide continuity in the event of failure of a failure of the system that rehash is run on. This key is a very high value secret, and needs to be protected that way. It should be made readable by only the userid on which the rehash daemon is run, and should be excluded from any backups made of the system that is running rehash.

Rehash should be run, if possible, on a dedicated system separate from and accessible only from the verifier(s) that it is performing hashing services for. It would normally be invoked from an init script at system boot up time. Use of facilities such as iptables is recommended to limit the accessibility of the hashing system.

Note that an attacker that is able to observe traffic between the verifier and the rehash system would have access to hashed salted memorized secrets that have not gone through the rehash process and are therefore potentially vulnerable to dictionary attack. Accordingly, the path between the verifier(s) and the rehash system need to be protected against eavesdropping, perhaps through the use of TLS (see “Future Work” below).

Operation and Use

Rehash accepts an HTTP POST request on TCP port 8888 containing a base64-encoded hash value to be rehashed. The following is an example of a request payload:

4i/qDyjZWTfwQvM4Lhcb9cBEGrALR6hX2ANuj4MAaUo=

Rehash responds with a similarly encoded hashed value:

Rk/Q5p20mWsQD0rpDZjfNtPbRlkWxCX0s8kgMHYcBFE=

Storage of rehashed memorized secrets of course depends on the authentication system it is being used with. It is recommended that the rehashed secrets be tagged to indicate the use of rehash, so that rehash can be integrated into existing password databases. A typical representation (used by Django) appears as follows:

pbkdf2_sha256$30000$PosCWw6yQTwU$4i/qDyjZWTfwQvM4Lhcb9cBEGrALR6hX2ANuj4MAaUo=

This might be replaced by something like:

pbkdf2_sha256_rehash$30000$PosCWw6yQTwU$Rk/Q5p20mWsQD0rpDZjfNtPbRlkWxCX0s8kgMHYcBFE=

Future Work

In its present form, rehash is a bare-bones proof of concept, probably not suitable for real production use. Here are some things that can be done to enhance rehash:

  1. External code review. The code is simple enough that it should be correct, but one should always make sure that all security-related code is competently reviewed.

  2. Use of TLS to secure the rehash transaction over HTTPS.

  3. Implementations in other languages besides Go.

  4. Support for more than one private key to allow a new key to be added in the event that there is suspicion that a private key has been compromised.

  5. Plug-in support for popular password-based authentication systems that would benefit from more secure password hashes.