Hi Udo and others,

I just integrated PBKDF2 hasher into ApplicationSecurity:
Usage example:

(ASPasswordVerifier new
������ hasher: ASPBKDF2Hasher new;
������ plainTextPassword: 'testPassword';
������ storedSalt: '590b223fc584ae96edf3d5dc7e363034';
������ storedFinalPassword: '2828efb46d56ca2fb004026398d412ef') verify.

Cheers,

Hern��n


2017-07-01 5:03 GMT-03:00 Udo Schneider <udo.schneider@homeaddress.de>:
Francis,

I can relate to the idea of easily embedding PBKDF2/bcrypt into your code. However the functionality of /managing/ the salt is not specificed in PBKDF2. The spec only covers the actual the hashing part. However wrapping it into a simple to use wrapper is pretty simple. The code below is something I use in my code for example:

"Create a new password instance"
pwd := KNPassword fromPlaintext: 'secret'.
"Now store that instance. It encapsulates hash, generated salt and
the load parameter. Because all the load parameters are accessed via
methods you can also back them with ivars and have different instances
with different load parameters. E.g. for adapting to advances in hash cracking."

pwd verify: 'secret'. "Verify the password"

CU,

Udo





'From Pharo5.0 of 16 April 2015 [Latest update: #50772] on 1 July 2017 at 10:01:05.207245 am'!
Object subclass: #KNPassword
�� �� �� �� instanceVariableNames: 'salt hash'
�� �� �� �� classVariableNames: 'PRNG'
�� �� �� �� poolDictionaries: ''
�� �� �� �� category: 'ThreatNews-Core'!

!KNPassword methodsFor: 'accessing' stamp: 'UdoSchneider 5/26/2017 11:48'!
salt
�� �� �� �� ^ salt
�� �� �� �� �� �� �� �� ifNil: [ salt := ((1 to: self saltLength) collect: [ :each | self class prng nextInt: 255 ])
�� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� asByteArray ]! !

!KNPassword methodsFor: 'accessing' stamp: 'UdoSchneider 7/1/2017 09:58'!
iterations
�� �� �� �� ^ 1000! !

!KNPassword methodsFor: 'accessing' stamp: 'UdoSchneider 7/1/2017 09:58'!
length
�� �� �� �� ^ 64! !

!KNPassword methodsFor: 'accessing' stamp: 'UdoSchneider 7/1/2017 09:58'!
saltLength
�� �� �� �� ^ 16! !

!KNPassword methodsFor: 'accessing' stamp: 'UdoSchneider 7/1/2017 09:57'!
hashClass
�� �� �� �� ^ SHA256! !


!KNPassword methodsFor: 'as yet unclassified' stamp: 'UdoSchneider 5/26/2017 11:51'!
setPlaintext: aString
�� �� �� �� hash := self hashString: aString! !

!KNPassword methodsFor: 'as yet unclassified' stamp: 'UdoSchneider 5/26/2017 11:52'!
verify: aString
�� �� �� �� ^ (self hashString: aString) = hash! !

!KNPassword methodsFor: 'as yet unclassified' stamp: 'UdoSchneider 5/26/2017 11:51'!
hashString: aString
�� �� �� �� ^ PBKDF2
�� �� �� �� �� �� �� �� derivedKeyHashFunction: self hashClass
�� �� �� �� �� �� �� �� password: aString
�� �� �� �� �� �� �� �� salt: self salt
�� �� �� �� �� �� �� �� iterations: self iterations
�� �� �� �� �� �� �� �� length: self length! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

KNPassword class
�� �� �� �� instanceVariableNames: ''!

!KNPassword class methodsFor: 'as yet unclassified' stamp: 'UdoSchneider 5/26/2017 11:49'!
reset
�� �� �� �� PRNG := nil! !

!KNPassword class methodsFor: 'as yet unclassified' stamp: 'UdoSchneider 5/26/2017 11:49'!
fromPlaintext: aString
�� �� �� �� ^ self new
�� �� �� �� �� �� �� �� setPlaintext: aString;
�� �� �� �� �� �� �� �� yourself! !

!KNPassword class methodsFor: 'as yet unclassified' stamp: 'UdoSchneider 5/26/2017 11:49'!
prng
�� �� �� �� ^ PRNG ifNil: [ PRNG := Random new ]! !