Attribute VB_Name = "basMD5pbe1"
Option Explicit
Option Base 0
Public Function Make_MD5_PBE(sPassword As String, abSalt() As Byte, nCount As Integer) As String
' Derives a password-based key using PBKDF1 algorithm and MD5 hash function. Ref: PKCS#5.
' Uses functions MD5_BytesHexHash() and cnvHexStrFromBytes() from
' CryptoSys (TM) API available from <http://www.cryptosys.net/>.
' This code was written in Visual Basic by David Ireland
' Copyright (C) 2003-6 DI Management Services Pty Ltd.
' First published 22 June 2003. Updated 17 May 2006.
Dim nRet As Long
Dim strHexDigest As String
Dim abMsg() As Byte
Dim abDigest() As Byte
Dim nLength As Long
Dim nLenSalt As Integer
Dim i As Integer
' Create concatenation of P || S
' Convert password string to Byte array
abMsg = StrConv(sPassword, vbFromUnicode)
' Append salt bytes
nLenSalt = UBound(abSalt) - LBound(abSalt) + 1
nLength = Len(sPassword) + nLenSalt
ReDim Preserve abMsg(nLength - 1)
For i = 0 To nLenSalt - 1
abMsg(Len(sPassword) + i) = abSalt(i)
Next
' Pre-dimension digest block to be 16 bytes (remember arrays are 0-based)
ReDim abDigest(API_MAX_MD5_BYTES - 1)
i = 1
'H(1) = MD5(P || S)
Debug.Print "P || S =", cnvHexStrFromBytes(abMsg)
nRet = MD5_BytesHash(abDigest(0), abMsg(0), nLength)
Debug.Print i, cnvHexStrFromBytes(abDigest)
' Length of input data is now 16
nLength = API_MAX_MD5_BYTES
' and we just repeatedly re-hash the previous digest
Do While i < nCount
' H(i) = MD5(H(i-1))
i = i + 1
nRet = MD5_BytesHash(abDigest(0), abDigest(0), nLength)
' For debugging purposes, we'll output some intermediate values
If (i <= 3 Or nCount - i < 3) Then
Debug.Print i, cnvHexStrFromBytes(abDigest)
End If
Loop
' Convert final result to a hex string
strHexDigest = cnvHexStrFromBytes(abDigest)
Make_MD5_PBE = strHexDigest
End Function
Public Function Test_MD5_PBE()
Dim sHexKey As String
Dim abSalt(7) As Byte
' Set salt = 78 57 8E 5A 5D 63 CB 06
abSalt(0) = &H78
abSalt(1) = &H57
abSalt(2) = &H8E
abSalt(3) = &H5A
abSalt(4) = &H5D
abSalt(5) = &H63
abSalt(6) = &HCB
abSalt(7) = &H6
sHexKey = Make_MD5_PBE("abc", abSalt, 1000)
Debug.Print "Derived key = " & sHexKey
' EXPECTED RESULTS:-
' 1 0e8baaeb3ced73cbc9bf4964f321824a
' 2 1f0554e6f8810739258c9abc60a782d5
' 3 aba6fedb4ad3efae8180364e617d9d79
' ...
' 1000 8fd6158bfe81add961241d8e4169d411
'Derived key = 8fd6158bfe81add961241d8e4169d411
End Function
Public Function Test_MD5_PBE_1()
Dim sHexKey As String
Dim abSalt(7) As Byte
' Change salt = 7D 60 43 5F 02 E9 E0 AE
abSalt(0) = &H7D
abSalt(1) = &H60
abSalt(2) = &H43
abSalt(3) = &H5F
abSalt(4) = &H2
abSalt(5) = &HE9
abSalt(6) = &HE0
abSalt(7) = &HAE
sHexKey = Make_MD5_PBE("abc", abSalt, 2048)
Debug.Print "Derived key = " & sHexKey
' EXPECTED RESULTS:-
' 1 4116f55b8bbc73af8e48833958f5bbca
' 2 eb7c2107b18f8227a5da327d1e0c97f7
' 3 504a7312c7a45e2ab15d4633e69b8053
' ...
' 2048 cc584d1ee305fb7ef65926f62e88dfe3
'Derived key = cc584d1ee305fb7ef65926f62e88dfe3
End Function