P-H-C / phc-winner-argon2

The password hash Argon2, winner of PHC
Other
4.78k stars 406 forks source link

Encode password to store in database - beginner's questions #278

Closed nicraMarcin closed 4 years ago

nicraMarcin commented 5 years ago

Hi everyone, I'm trying to encrypt password to stroe it in database. First I use example code from readme to test.

#include "argon2.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>

#define HASHLEN 32
#define SALTLEN 16
#define PWD "password"

string PasswordEncoder::encode(string plainPassword) {

    uint8_t hash1[HASHLEN];
    uint8_t hash2[HASHLEN];
    char encoded[97];

    uint8_t salt[SALTLEN];
    memset( salt, 0x00, SALTLEN );

    uint8_t *pwd = (uint8_t *)strdup(PWD);
    uint32_t pwdlen = strlen((char *)pwd);

    uint32_t t_cost = 2;            // 1-pass computation
    uint32_t m_cost = (1<<16);      // 64 mebibytes memory usage
    uint32_t parallelism = 1;       // number of threads and lanes

    // high-level API
    argon2i_hash_raw(t_cost, m_cost, parallelism, pwd, pwdlen, salt, SALTLEN, hash1, HASHLEN);
    argon2i_hash_encoded(t_cost, m_cost, parallelism, pwd, pwdlen, salt, SALTLEN, HASHLEN, encoded, 97);

    // low-level API
    argon2_context context = {
            hash2,  /* output array, at least HASHLEN in size */
            HASHLEN, /* digest length */
            pwd, /* password array */
            pwdlen, /* password length */
            salt,  /* salt array */
            SALTLEN, /* salt length */
            NULL, 0, /* optional secret data */
            NULL, 0, /* optional associated data */
            t_cost, m_cost, parallelism, parallelism,
            ARGON2_VERSION_13, /* algorithm version */
            NULL, NULL, /* custom memory allocation / deallocation functions */
            /* by default only internal memory is cleared (pwd is not wiped) */
            ARGON2_DEFAULT_FLAGS
    };

    free(pwd);

    for( int i=0; i<HASHLEN; ++i )
        printf( "%02x", hash1[i] ); printf( "\n" );

    if (memcmp(hash1, hash2, HASHLEN)) {
        for( int i=0; i<HASHLEN; ++i ) {
            printf( "%02x", hash2[i] );
        }
        printf("\nfail\n");
    }
    else printf("ok\n");

    std::cout << "encoded password: " << encoded << std::endl;

    return encoded;

}

Now, when I run it I see that two diffrent hashes are generated for high level and low level.

26dafa2c5bf87a7263ae77bcf1ad8bd9413ca8317e2da931ac0af84102995976
307418f3fe7f000025f4abe7aa5500001df4abe7aa550000307518f3fe7f0000
fail
encoded password: $argon2i$v=19$m=65536,t=2,p=1$sdMe5h0RTWAH+Z87Q5Tq0Q$Jtr6LFv4enJjrne88a2L2UE8qDF+LakxrAr4QQKZWXY

Shouldnt be the same?

SantiagoTorres commented 5 years ago

I may have misread your snippet, but is the context used at all?

nicraMarcin commented 5 years ago

@SantiagoTorres yes, you are right, I didn't copy all code from example and hash2 variable contained rubbish data. Later I made tests encoding and verifying passwords and all worked well.