Phpass password hashing for Lua
13 May 2015phpass (pronounced “pH pass”) is a portable public domain password hashing framework for use in PHP applications. phpass has been integrated into WordPress 2.5+, bbPress, Vanilla, PivotX 2.1.0+, Chyrp, Textpattern 4.4.0+, and concrete5 5.6.3+.
Lua module lua-phpass implements a subset of phpass (iterated MD5). It’s sufficient to create and check a password hash compatible with portable phpass hash, e.g. a password from wordpress database. Blowfish-based bcrypt and BSDI-style extended DES-based hashes are not supported.
This module is distributed under terms of the MIT License.
Installation
$ luarocks install phpass
Dependencies
The code was tested against Lua 5.1, 5.2, 5.3 and LuaJIT 2.0, 2.1.
LuaCrypto for Lua 5.3 requires the following patch:
diff --git a/src/lcrypto.c b/src/lcrypto.c
index 48364d1..e5a62c4 100644
--- a/src/lcrypto.c
+++ b/src/lcrypto.c
@@ -968,7 +968,7 @@ static int verify_fverify(lua_State *L)
static int rand_do_bytes(lua_State *L, int (*bytes)(unsigned char *, int))
{
- size_t count = (size_t)luaL_checkint(L, 1);
+ size_t count = (size_t)luaL_checkinteger(L, 1);
unsigned char tmp[256], *buf = tmp;
if (count > sizeof tmp)
buf = (unsigned char *)malloc(count);
I have applied this patch to my fork of LuaCrypto. There is also the modified version of rockspec for version 0.3.2, which installs modified LuaCrypto.
Usage
phpass = require 'phpass'
password = 'test12345'
hash = phpass.hashPassword(password)
--> "$P$EYyDnrNHtS2MG5vTVkvXD6wMnd0C/N/"
phpass.checkPassword(password, hash) --> true
phpass.checkPassword('other password', hash) --> false
Notes
Python-phpass, python implementation of phpass was used as a reference.
The algorithm used in phpass.hashPassword
generates random
salt, so this function returns different hashes for a password.
phpass.hashPassword
has second argument, count_log2
,
which is log2
of number of iterations. The algorithm of
hashing is as follows:
count = 2 ^ count_log2
salt = ...
hash = md5(salt .. password)
for i = 1, count do
hash = md5(hash .. password)
end