UB authentication schema #

Actually this is modified DIGEST schema with SHA256 hash algorithm and modified authorization mechanism. In case of this schema usage UnityBase store client passwords hash in upasswordHashHexa attribute of uba_user entity. Schema is protected from MIT type of attack and secure enough for most type of application.

On the UI client enter a userName & password, after this client must send a two request:

1) Request a nonce #

Client call auth endpoint passing userName as parameter.

-> GET|POST /auth?AUTHTYPE=UB&userName=admin

Server return a serverNonce - one time public key valid for 5 minutes in a result field

<- 200 OK
{"result":"c0a94994a9baaf5f6f071a13c6b5f7c4f8219e1ba514d9f0b81df57cc4b4b81f"}

2) Sending hashed password and obtain a sessionWord #

Client generate clientNonce, calculate hash of his password and call auth again, passing as parameters userName, clientNonce and password hashed with nonces.

-> GET|POST /auth?AUTHTYPE=UB&
    clientNonce=ffac6401331cce72e82ecfa8dd40c8cb4456098000392da2bac8c41d19b57467&
    password=09561d07211a8ef1d125355bfb5e871028826484a30bde6c98562742d2e9460e
    &userName=admin

here:

clientNonce = unique string client generate and memorize
secretWord = sha256('salt' + passwordWhatUserEnterDuringLogin)
password=sha256('/' + serverNonce + clientNonce + userName + secretWord)

Server return sessionPrivateKey, used in future request as one of signature part.

    <- 200 OK
{
    "result":"537445910+634e82b0aa70c0ec67395d59935f1cec36c14cedc4cc824049e175109987d1c6",
    "logonname":"admin",
    "uData": {}
}

result in response is a sessionPrivateKey. First part of result before + is clientSessionID.

See UB authorization for authorization token calculation.

Consider what neither password, nor password hash not transferred other the wire, so the MIT attack is impossible.

JavaScript implementation:

var secretWord, sessionPrivateKey, hexa8ID;
promise = me.get('auth', {
    params: {
        AUTHTYPE: authSchema,
        userName: authParams.login
    }
}).then(function(resp){
    var
        serverNonce = resp.data.result,
        SHA256 = CryptoJS.SHA256;
    if (!serverNonce) throw new Error('invalid auth response');
    var clientNonce = SHA256(new Date().toISOString().substr(0, 16)).toString();
    var pwdHash = SHA256('salt' + authParams.password).toString();
    secretWord = pwdHash;
    return me.get('auth', {
        params: {
            AUTHTYPE: authSchema,
            userName: authParams.login,
            password: SHA256('/' + serverNonce + clientNonce + authParams.login + pwdHash).toString(),
            clientNonce: clientNonce
        }
    });
}).then(function(response){
    sessionPrivateKey = response.result;
    hexa8ID = hexa8(sessionWord.split('+')[0]);
});