The point of bcrypt is that is has been carefully designed to resist brute forcing, it is specifically designed to be slow and not optimisable with GPUs etc. In practice it would takes decades, or centuries to brute force a correctly implemented bcrypt hash. There is a good explanation of why here
https://auth0.com/blog/hashing-in-action-understanding-bcrypt/
________________________________
From: MIDRANGE-L <midrange-l-bounces@xxxxxxxxxxxxxxxxxx> on behalf of Rob Berendt <rob@xxxxxxxxx>
Sent: 18 March 2021 13:06
To: Midrange Systems Technical Discussion <midrange-l@xxxxxxxxxxxxxxxxxx>
Subject: RE: How to validate passwords without storing them anywhere.
But again, if you're using a known approved encryption, like bcrypt, and someone downloads the database, can't they just brute force it by hammering on bcrypt the same as brute force it by hammering on the sql function?
Does it make any difference to the following:
If ValidSignon(userid, password) ...
to a brute force attacker if the code behind ValidSignon is written with the sql function or bcrypt?
Rob Berendt
--
IBM Certified System Administrator - IBM i 6.1
Group Dekko
Dept 1600
Mail to: 7310 Innovation Blvd, Suite 104
Ft. Wayne, IN 46818
Ship to: 7310 Innovation Blvd, Dock 9C
Ft. Wayne, IN 46818
http://www.dekko.com
-----Original Message-----
From: MIDRANGE-L <midrange-l-bounces@xxxxxxxxxxxxxxxxxx> On Behalf Of Tim Fathers
Sent: Thursday, March 18, 2021 8:24 AM
To: Midrange Systems Technical Discussion <midrange-l@xxxxxxxxxxxxxxxxxx>
Subject: Re: How to validate passwords without storing them anywhere.
CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
The problem of storing passwords securely has already been solved though, hasn't it? Hash with a salt using something designed for the job, like bcrypt. The salt itself, which doesn't have to be kept secret, it is generated by bcrypt and returned as part of the hash, which is stored in the database. I don't think it's a good idea to reinvent this particular wheel.
Tim.
________________________________
From: MIDRANGE-L <midrange-l-bounces@xxxxxxxxxxxxxxxxxx> on behalf of Rob Berendt <rob@xxxxxxxxx>
Sent: 18 March 2021 11:10
To: Midrange Systems Technical Discussion <midrange-l@xxxxxxxxxxxxxxxxxx>
Subject: RE: How to validate passwords without storing them anywhere.
Thank you Jonathan. I thought about the read triggers and all that. Good reading.
Rob Berendt
--
IBM Certified System Administrator - IBM i 6.1
Group Dekko
Dept 1600
Mail to: 7310 Innovation Blvd, Suite 104
Ft. Wayne, IN 46818
Ship to: 7310 Innovation Blvd, Dock 9C
Ft. Wayne, IN 46818
http://www.dekko.com
-----Original Message-----
From: MIDRANGE-L <midrange-l-bounces@xxxxxxxxxxxxxxxxxx> On Behalf Of Wilson, Jonathan
Sent: Wednesday, March 17, 2021 5:05 PM
To: midrange-l@xxxxxxxxxxxxxxxxxx
Subject: Re: How to validate passwords without storing them anywhere.
CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
On Wed, 2021-03-17 at 13:03 -0600, Nathan Andelin wrote:
I think the idea using a password to encrypt and decrypt a string has
merit, however as with all security measures there seem to be
tradeoffs.
You're using standard SQL procedures to encrypt and decrypt a
"common"
string; By common, I'm referring in this case to your use of the word
"VALID" in ENCRYPT_TDES() and DECRYPT_CHAR() procedures. What happens
when
that common string "VALID" becomes generally known?
I think the point is that it doesn't matter if it becomes known... it
gets you nowhere. The password is used to hash a word and then
that re-encoded hash is compared to the previously hashed word
in the file. There is no way to get back to a password, but only a
valid password produces an equal comparison of the database word.
It wouldn't stop brute force, nothing will - except time and possibly a
max login attempt counter (Not sure if its possible but I guess you
could use a read trigger, if such a thing exists, to increment a
counter and then if a valid signon happens you re-set the trigger count
and if the count is exceeded you disable the read returning "no record"
or don't retrun some kind of valid token).
If anything its much safer because if the file was to become
compromised and someone brute forced they would get to know nothing but
"theword" (which doesn't even need to be a word, it could be a random
blob of data that was 1024 bytes long encapsulating every hex value)
and would have to brute force every password row by row.
I guess you could also do some odd stuff like hash the username with
the password and a seed to create a hashed username and then a
different seed for the password encoded blob. Then even more
information has to be brute forced, row by row. And also don't use
sequential numeric id's as PK's (easy to guess, something like GUID's
are much better)
Everything depends on what you are trying to do, and what you are
trying to prevent and what kind of information would leak if your
database/table got out into the wild. However if someone has access to
the raw database (to load on to their system to run attacks against)
you have bigger problems than if someone can brute force password
hashes, row by row, slowly. (Note that as you don't store the hashed
passwords, but use them to hash the unique blob, rainbow tables are not
as easy to use (possible, but convoluted). Also, you kinda have a
chicken and egg situation... you need to be able to log on to get the
data which requires logon access to be able to get it... obviously all
bets are off if they can get the salt and/or pepper and the full user
table to play with at their leisure. But obviously you'd never have
master user within a user table that matched the database admin logon
and that matched the OS logon because that would be just silly ;-)
(says me, who did do just that on my home linux system while playing
with wordpress and LAMP - ooops!) .)
I should note that the salts (well peppers) shouldn't really be stored
within the DB but somewhere else (a non-db file perhaps, or possibly
hardcoded within a program) but then again, if someone has access to
your full DB they may have access to your program objects, or possibly
your source code. There is only so far you can go and you have to trust
someone to "know the sensitive stuff" and some programs have to be able
to access the sensitive stuff to be able to work. There are also other
methods of hashing that are less prone to lookup (rainbow) tables and
are much slower and the such like.
I find this
https://security.stackexchange.com/questions/17421/how-to-store-salt
(the TL:DR reply) is rather a good explanation of hashes and seeds and
peppers and stuff.
Once you start going down this rabbit hole, it ends up becoming very
"inception" like with layer on layer on layer and at each stage you ask
"but what if they had...?"
Also, since the encrypted value is stored in a database, what would
prevent
someone from using SQL SELECT with DECRYPT_CHAR() in a brute-force
attack
to find out all the passwords?
On Wed, Mar 17, 2021 at 12:46 PM Calvin Buckley <calvin@xxxxxxxxxx>
wrote:
This sample is really concerning without any attention to
salting... or
cryptography. Not only is 3DES very busted, it's also not the
appropriate algorithm assuming it's secure. You'd want one-way
hashing
(the archetypical example is MD5, but it too is old and busted),
plus
salting so someone can't just precompute a bunch of hashes.
Ideally, you'd want password hashing algorithms designed special-
purpose, like bcrypt (disclaimer: I have an ILE port of bcrypt, all
open source). Those are specifically optimized for password hashing
by
being expensive to hash, whereas MD5/SHA are designed to be cheap
(because they're designed for general integrity).
On Wed, 2021-03-17 at 17:29 +0000, Rob Berendt wrote:
-- How to verify passwords without ever storing passwords.
-- Thanks to Darren Strong of Dekko.
-- The basic concept is that you do not store the password.
-- Instead you store a common string encrypted by the password.
-- As a war on 5250 tools the "short names" are obscured.
set current schema = 'ROB';
CREATE OR REPLACE TABLE Security_table for system name T000000001
(
Security_id for column C000000001 varchar(100) ALLOCATE(10)
not
null constraint Security_table_primary_key PRIMARY KEY,
Security_name for column C000000002 varchar(100) ALLOCATE(25)
not
null,
Password_Encryption for column C000000003 varchar(256) FOR
BIT
DATA
)
RCDFMT T00000001R
;
-- Let's say the password is Budweiser#01.
-- So you encrypt the word VALID with that as an encryption key
and
all you are really storing is VALID.
insert into Security_table (
Security_id, Security_name, Password_Encryption)
Values('ROB', 'Rob Berendt', ENCRYPT_TDES(varchar('VALID'),
'Budweiser#01'));
-- Now when they enter their password you pass that as a
decryption
key to see if it is valid.
Select DECRYPT_CHAR(Password_Encryption, 'Budweiser#01')
from Security_table
where Security_id = 'ROB';
-- Test to see if the user 'ROB' was found'
-- Test to see if the encryption key was valid by checking the
value
returned.
-- If the value returned was not the word VALID the person
entered an
invalid password.
-- Or don't let the user know they guessed the userid and return
generic error if either is invalid.
Rob Berendt
--
IBM Certified System Administrator - IBM i 6.1
Group Dekko
Dept 1600
Mail to: 7310 Innovation Blvd, Suite 104
Ft. Wayne, IN 46818
Ship to: 7310 Innovation Blvd, Dock 9C
Ft. Wayne, IN 46818
http://www.dekko.com
--
This is the Midrange Systems Technical Discussion (MIDRANGE-L)
mailing list
To post a message email: MIDRANGE-L@xxxxxxxxxxxxxxxxxx
To subscribe, unsubscribe, or change list options,
visit: https://lists.midrange.com/mailman/listinfo/midrange-l
or email: MIDRANGE-L-request@xxxxxxxxxxxxxxxxxx
Before posting, please take a moment to review the archives
at https://archive.midrange.com/midrange-l.
Please contact support@xxxxxxxxxxxxxxxxxxxx for any subscription
related
questions.
Help support midrange.com by shopping at amazon.com with our
affiliate
link: https://amazon.midrange.com
--
This is the Midrange Systems Technical Discussion (MIDRANGE-L) mailing list
To post a message email: MIDRANGE-L@xxxxxxxxxxxxxxxxxx
To subscribe, unsubscribe, or change list options,
visit:
https://lists.midrange.com/mailman/listinfo/midrange-l
or email: MIDRANGE-L-request@xxxxxxxxxxxxxxxxxx
Before posting, please take a moment to review the archives
at
https://archive.midrange.com/midrange-l.
Please contact support@xxxxxxxxxxxxxxxxxxxx for any subscription related questions.
Help support midrange.com by shopping at amazon.com with our affiliate link:
https://amazon.midrange.com
--
This is the Midrange Systems Technical Discussion (MIDRANGE-L) mailing list
To post a message email: MIDRANGE-L@xxxxxxxxxxxxxxxxxx
To subscribe, unsubscribe, or change list options,
visit:
https://lists.midrange.com/mailman/listinfo/midrange-l
or email: MIDRANGE-L-request@xxxxxxxxxxxxxxxxxx
Before posting, please take a moment to review the archives
at
https://archive.midrange.com/midrange-l.
Please contact support@xxxxxxxxxxxxxxxxxxxx for any subscription related questions.
Help support midrange.com by shopping at amazon.com with our affiliate link:
https://amazon.midrange.com
--
This is the Midrange Systems Technical Discussion (MIDRANGE-L) mailing list
To post a message email: MIDRANGE-L@xxxxxxxxxxxxxxxxxx
To subscribe, unsubscribe, or change list options,
visit:
https://lists.midrange.com/mailman/listinfo/midrange-l
or email: MIDRANGE-L-request@xxxxxxxxxxxxxxxxxx
Before posting, please take a moment to review the archives
at
https://archive.midrange.com/midrange-l.
Please contact support@xxxxxxxxxxxxxxxxxxxx for any subscription related questions.
Help support midrange.com by shopping at amazon.com with our affiliate link:
https://amazon.midrange.com
--
This is the Midrange Systems Technical Discussion (MIDRANGE-L) mailing list
To post a message email: MIDRANGE-L@xxxxxxxxxxxxxxxxxx
To subscribe, unsubscribe, or change list options,
visit:
https://lists.midrange.com/mailman/listinfo/midrange-l
or email: MIDRANGE-L-request@xxxxxxxxxxxxxxxxxx
Before posting, please take a moment to review the archives
at
https://archive.midrange.com/midrange-l.
Please contact support@xxxxxxxxxxxxxxxxxxxx for any subscription related questions.
Help support midrange.com by shopping at amazon.com with our affiliate link:
https://amazon.midrange.com
As an Amazon Associate we earn from qualifying purchases.