Reversing a password-hashing function knowing plaintext + output - hash

I have a password that has been stored and I'd like to figure out how it's been 'transformed' to be stored in my database.
The plaintext password is:
k4oK203$
And the password as it is stored 'crypted' in my database is:
6xqmRr0QNUrc0uvwGchWqA==
How would I go about figuring out what transformation (base64? sha1? md5? etc.) that were used in order to get the plain text password in to the database value?

Related

postgres store hash string: invalid message format

In my node.js application I should be able to create some new users.
And to store the passwords in a secure fashion, I use the sodium-native library to generate argon2 hashes (https://github.com/sodium-friends/sodium-native). Now I try to store a string representation of those hashes in my postgres database.
The JavaScript query string looks like this:
INSERT INTO users (email, name, password) VALUES ('${email}', '${name}', '${pwHash}')
And the generated sql statement looks as follows:
INSERT INTO users (email, name, password)
VALUES ('test#test.org', 'test', '$argon2id$v=19$m=8,t=1,p=1$WAw+HmO/+RZTazVr3eOnPg$HYzaB0+Cre23XGR+A1cZawrUvkon2Cx3x7ua5I68xGo ')
Besides the hash, there is some further information stored about it to help verify passwords.
I don't know why it produces all those white-spaces, but I think it is due to the fixed length of the buffer used.
My problem is that postgres, for some reason, sends me an error: invalid message format, code: '08P01'Now, that code means protocol violation, whatever that means.
The funny thing is: when I just hard code the hash as it appears in my browser or console, then it works:
INSERT INTO users (email, name, password)
VALUES ('${email}', '${name}', '$argon2id$v=19$m=8,t=1,p=1$WAw+HmO/+RZTazVr3eOnPg$HYzaB0+Cre23XGR+A1cZawrUvkon2Cx3x7ua5I68xGo ')
It doesn't seem to make a difference, if I remove the white-spaces or not.
Can anybody tell me what I am doing wrong?
Edit: I was asked if those "blanks" really are white-spaces. At least I think so, because they appear as ones in the editor and browser and copy as ones as well. I tried to manually remove them and it didn't make any difference.
I also tried to use string concatenation instead of interpolation, but it also didn't make any difference.
Instead of converting the buffer to a string first, I now store the hash as raw binary data (data-type bytea) as it is generated by sodium-native. That also makes password verification trivial. Please do follow mu is too short's advise about SQL injection.

Is there a way to disable Redshift password requirements?

According to Amazon Redshift docs, the passwords must be at least 8 chars, and contain at least one uppercase letter, one lowercase letter, and one number.
Is there a way to disable this for a database?
We do not need such stringent requirements.
Also, the docs are unclear, but if I don't specify VALID UNTIL 'something' then it is valid forever, right? (The docs say you can also use VALID UNTIL 'infinity' but don't explain what would happen if you don't include VALID UNTIL at all)
You cannot modify the Redshift password criteria.
If you are referring to ALTER USER ... [VALID UNTIL], the validity date is not a required field. The password will remain valid forever.
By using the md5 function, you can get around the lengh/char requirements:
https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_USER.html
In particular, quoting from the above page:
To specify an MD5 password, follow these steps:
Concatenate the password and user name.
For example, for password ez and user user1, the concatenated string is ezuser1.
Convert the concatenated string into a 32-character MD5 hash string. You can use any MD5 utility to create the hash string. The following example uses the Amazon Redshift MD5 Function and the concatenation operator ( || ) to return a 32-character MD5-hash string.
select md5('ez' || 'user1');
md5
153c434b4b77c89e6b94f12c5393af5b
Concatenate 'md5' in front of the MD5 hash string and provide the concatenated string as the md5hash argument.
create user user1 password 'md5153c434b4b77c89e6b94f12c5393af5b';
Log on to the database using the user name and password.
For this example, log on as user1 with password ez.

Password hashing and salting

I'm trying to wrap my head around the logic of encrypting passwords with MD5/SHA combined with salting.
I understand the concept of a user proving a text password, and appending a random string (salt) to the text password, and hashing the final string via whatever encryption method you want.
This is where I lose the concept
Say in my database of users, I have usernames, and encrypted passwords generated with the random salt value
When the user goes to log into a system, and they enter their password, how do I obtain the correct salt to check the password validity?
If the salt is randomly generated to begin with, I can't recalculate it
Do I have to store the salt with the username/password record? If I query the database for the salt value by username, it would seem that defeats the purpose of having the salting.
How do I obtain the correct salt when it comes time to validate the supplied password?
From Wikipedia, Salt (cryptography)
A new salt is randomly generated for each password. In a typical setting, the salt and the password are concatenated and processed with a cryptographic hash function, and the resulting output (but not the original password) is stored with the salt in a database
You store it with the hash, to prevent dictionary attacks.
The salt is stored in the database, so you can use the same salt to verify the password. Todays libraries often will include the salt in the resulting hash-value like this (result of the PHP function password_hash()):
$2y$10$nOUIs5kJ7naTuTFkBy1veuK0kSxUFXfuaOKdOKf9xYT0KKIGSJwFa
| | | |
| | | hash-value = K0kSxUFXfuaOKdOKf9xYT0KKIGSJwFa
| | |
| | salt = nOUIs5kJ7naTuTFkBy1veu (22 characters)
| |
| cost-factor = 10 = 2^10 iterations
|
hash-algorithm = 2y = BCrypt
This 60 character string can be stored into a single field in the database. The verifying function can extract the salt from this string. The salt is not a secret, it fulfills its purpose even when it is known.
Please note that algorithms like MD5 and SHA-* are not appropriate to hash passwords, because they are too fast. Instead use an algorithm with a cost factor like BCrypt or PBKDF2. For more information you can have a look at my tutorial about safely storing passwords.
Yes, you store the salt. Salting is used to prevent pregenerated rainbow tables, it is not required to be secret, just unpredictable.

AES_Encrypt : Password getting reset automatically

I am using AES_Encrypt('123456',2) to store my password in db in encrypted format.
I have noticed that after some time the password stored in db automatically gets reset to NULL. I have cross checked this by using AES_Decrypt.
I don't know why is this happening. I am not updating my password anywhere in the code. Then I am wondering how come and when is the password getting reset. Does it has anything to do with the AES_Encrypt?
Assuming that you are referring to the MySQL AES_ENCRYPT and AES_DECRYPT routines I will direct you to the reference which states that
AES_ENCRYPT() encrypts a string and returns a binary string. AES_DECRYPT() decrypts the encrypted string and returns the original string. The input arguments may be any length. If either argument is NULL, the result of this function is also NULL.
If AES_DECRYPT() detects invalid data or incorrect padding, it returns NULL. However, it is possible for AES_DECRYPT() to return a non-NULL value (possibly garbage) if the input data or the key is invalid.
Is it possible that either of your functions could be getting supplied with invalid data or incorrect padding?
Additionally, the AES_ENCRYPT function may pad your data out to a specific length. Ensure you are not truncating to fit within your database

Error "invalid byte sequence for encoding UTF8" on insert into BYTEA

is there any pair of encrypt and respective decrypt function?
Functions In PGCRYPTO library uses hash algorithms so they don't have decryption functions.
Also when I am using pgp_sym_encrypt() and pgp_sym_decrypt() functions,
pgp_sym_decrypt() function gives the above error for encrypted value of pgp_sym_encrypt().
I am using Postgres Plus Advanced Server 8.4.
Do I have to put \ before every escape sequence character or what?
Please provide the solution how to access bytea data and also put encrypted value in
table column and decrypt the same value.
Thanks
Tushar
If you encrypt/decrypt binary data you should use pgp_sym_encrypt_bytea and pgp_sym_decrypt_bytea functions.
The functions pgp_sym_encrypt and pgp_sym_decrypt are for textual data which has to be encoded in client encoding and possible to convert to database encoding. So you can not use them for example to encrypt images, PDFs etc.