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