Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PBKDF2作为Excel中的函数_Excel_Vba_Pbkdf2 - Fatal编程技术网

PBKDF2作为Excel中的函数

PBKDF2作为Excel中的函数,excel,vba,pbkdf2,Excel,Vba,Pbkdf2,我已经设法让SHA256哈希在Excel中工作,但我正在寻找更安全的东西,我在这里遇到了PBKDF2哈希生成: 但解决方案中的代码不运行: 编译错误:未定义用户定义的类型 突出显示以下内容: Function HMAC(ByVal plainText As String, _ ByVal algoritm As hmacAlgorithm, _ Optional ByVal key As String, _ Optional ByVal decodeKey As keyD

我已经设法让SHA256哈希在Excel中工作,但我正在寻找更安全的东西,我在这里遇到了PBKDF2哈希生成: 但解决方案中的代码不运行:

编译错误:未定义用户定义的类型

突出显示以下内容:

Function HMAC(ByVal plainText As String, _
    ByVal algoritm As hmacAlgorithm, _
    Optional ByVal key As String, _
    Optional ByVal decodeKey As keyDecoding = kdNone_String, _
    Optional ByVal encodeHash As hashEncoding = heBase64) As Variant
我最终的希望是有一个类似于SHA256的函数,我有=SHA256hash(A2),其中PBKDF2 keylength、salt和iterations作为选项 =PBKDF2(A2512,盐析盐,5000) 例如,这里的团队实施起来很简单,我们都知道,实施起来越困难,人们就越不可能这么做

上述链接上的代码为:

枚举

Enum hmacAlgorithm
    HMAC_MD5
    HMAC_SHA1
    HMAC_SHA256
    HMAC_SHA384
    HMAC_SHA512
End Enum

Enum hashEncoding
    heBase64
    heHex
    heNone_Bytes
End Enum
PBKDF2功能

Function PBKDF2(ByVal password As String, _
    ByVal salt As String, _
    ByVal hashIterations As Long, _
    ByVal algoritm As hmacAlgorithm, _
    Optional ByVal dkLen As Long, _
    Optional ByVal encodeHash As hashEncoding = heBase64) As Variant

'https://tools.ietf.org/html/rfc2898 - PKCS #5: Password-Based Cryptography Specification Version 2.0
'https://tools.ietf.org/html/rfc6070 - PKCS #5: Password-Based Key Derivation Function 2 (PBKDF2) Test Vectors
'https://en.wikipedia.org/wiki/PBKDF2

'DK = T1 || T2 || ... || Tdklen/hlen
'Ti = F(password, salt, c, i)
'
'F(Password, Salt, c, i) = U1 ^ U2 ^ ... ^ Uc
'
'U_1 = PRF (P, S || INT (i)) (INT (i) is a four-octet encoding of the integer i, most significant octet first.)
'U_2 = PRF (P, U_1)
'...
'U_c = PRF (P, U_{c-1})

Dim utf8Encoding As Object
Dim hashManager As Object

Dim hLen As Long
Dim noBlocks As Long
Dim noBlock As Long

Dim hmacKeyBytes() As Byte
Dim saltBytes() As Byte
Dim uboundSaltBytes As Long

Dim hmacBytes() As Byte
Dim tempBytes() As Byte
Dim outputBytes() As Byte

Dim i As Long
Dim j As Long

'Create utf8-encoding object
Set utf8Encoding = CreateObject("System.Text.UTF8Encoding")

'Create hmac object
Select Case algoritm
    Case HMAC_MD5
        Set hashManager = CreateObject("System.Security.Cryptography.HMACMD5")
    Case HMAC_SHA1
        Set hashManager = CreateObject("System.Security.Cryptography.HMACSHA1")
    Case HMAC_SHA256
        Set hashManager = CreateObject("System.Security.Cryptography.HMACSHA256")
    Case HMAC_SHA384
        Set hashManager = CreateObject("System.Security.Cryptography.HMACSHA384")
    Case HMAC_SHA512
        Set hashManager = CreateObject("System.Security.Cryptography.HMACSHA512")
End Select

'Check the length of the blocks to be generated
hLen = hashManager.HashSize / 8

'Calculate amount of blocks 'T'
If dkLen = 0 Then dkLen = hLen
noBlocks = Application.WorksheetFunction.Ceiling(dkLen / hLen, 1)

'Encode the key and salt to bytes
hmacKeyBytes = utf8Encoding.GetBytes_4(password)
saltBytes = utf8Encoding.GetBytes_4(salt)

'Set the key in the crypto class
hashManager.key = hmacKeyBytes

'Get the length of the salt, add 4 to concatenate INT(I)
uboundSaltBytes = UBound(saltBytes) + 4

'Loop T1 || T2 || ... || Tdklen/hlen
For i = 1 To noBlocks

    'Salt || INT(i)
    'INT (i) is a four-octet encoding of the integer i, most significant octet first.
    tempBytes = saltBytes
    ReDim Preserve tempBytes(uboundSaltBytes)
    noBlock = i

    'Calculate INT(i) of Salt || INT(i)
    For j = 3 To 0 Step -1
        tempBytes(uboundSaltBytes - j) = Int(noBlock / (255 ^ j))
        noBlock = noBlock - Int(noBlock / (255 ^ j)) * 255 ^ j
    Next j

    'Hash U1: Salt || INT(i)
    hmacBytes = hashManager.ComputeHash_2(tempBytes)
    tempBytes = hmacBytes

    'Hash, Xor: U1 ^ U2 ^ ... ^ Uc
    For j = 1 To hashIterations - 1
        hmacBytes = hashManager.ComputeHash_2(hmacBytes)
        tempBytes = XorBytes(tempBytes, hmacBytes)
    Next j

    'For the first block outputBytes() is empty
    If i = 1 Then
        outputBytes = tempBytes
    Else
        ConcatenateArrayInPlace outputBytes, tempBytes
    End If

Next i

'Extract the first dkLen octets to produce a derived key DK:
ReDim Preserve outputBytes(dkLen - 1)

'Base64, Hex, or Byte() output
If encodeHash = heBase64 Then
    PBKDF2 = Encode(outputBytes, edBase64)
ElseIf encodeHash = heHex Then
    PBKDF2 = Encode(outputBytes, edHex)
Else
    PBKDF2 = outputBytes
End If

Set hashManager = Nothing
Set utf8Encoding = Nothing

End Function
Function HMAC(ByVal plainText As String, _
    ByVal algoritm As hmacAlgorithm, _
    Optional ByVal key As String, _
    Optional ByVal decodeKey As keyDecoding = kdNone_String, _
    Optional ByVal encodeHash As hashEncoding = heBase64) As Variant

Dim hashManager As Object

Dim hashBytes() As Byte
Dim hmacKeyBytes() As Byte

'Create the specific hash manager based on the hash algoritm
Select Case algoritm
    Case HMAC_MD5
        Set hashManager = CreateObject("System.Security.Cryptography.HMACMD5") 'Returns 128 bits, 16 bytes
    Case HMAC_SHA1
        Set hashManager = CreateObject("System.Security.Cryptography.HMACSHA1") 'Returns 160 bits, 20 bytes
    Case HMAC_SHA256
        Set hashManager = CreateObject("System.Security.Cryptography.HMACSHA256") 'Returns 256 bits, 32 bytes
    Case HMAC_SHA384
        Set hashManager = CreateObject("System.Security.Cryptography.HMACSHA384") 'Returns 384 bits, 48 bytes
    Case HMAC_SHA512
        Set hashManager = CreateObject("System.Security.Cryptography.HMACSHA512") 'Returns 512 bits, 64 bytes
End Select

'Encode the plaintText to bytes
hashBytes = UTF8_GetBytes(plainText)

If key = vbNullString Then

    'Get the key generated by the hashManager
    hmacKeyBytes = hashManager.key

    'Calculate the hash
    hashBytes = hashManager.ComputeHash_2(hashBytes)

    'Return encoded result
    If encodeHash = heBase64 Then
        HMAC = "<Key>" & Encode(hmacKeyBytes, edBase64) & "<Key>" & vbCrLf & Encode(hashBytes, edBase64)
    ElseIf encodeHash = heHex Then
        HMAC = "<Key>" & Encode(hmacKeyBytes, edHex) & "<Key>" & vbCrLf & Encode(hashBytes, edHex)
    End If

Else

    'Decode and set the key
    Select Case decodeKey
    Case kdBase64
        hashManager.key = Decode(key, edBase64)
    Case kdHex
        hashManager.key = Decode(key, edHex)
    Case Else
        hashManager.key = UTF8_GetBytes(key)
    End Select

    'Calculate the hash
    hashBytes = hashManager.ComputeHash_2(hashBytes)

    'Return encoded result
    If encodeHash = heBase64 Then
        HMAC = Encode(hashBytes, edBase64)
    ElseIf encodeHash = heHex Then
        HMAC = Encode(hashBytes, edHex)
    End If

End If

Set hashManager = Nothing

End Function
HMAC功能

Function PBKDF2(ByVal password As String, _
    ByVal salt As String, _
    ByVal hashIterations As Long, _
    ByVal algoritm As hmacAlgorithm, _
    Optional ByVal dkLen As Long, _
    Optional ByVal encodeHash As hashEncoding = heBase64) As Variant

'https://tools.ietf.org/html/rfc2898 - PKCS #5: Password-Based Cryptography Specification Version 2.0
'https://tools.ietf.org/html/rfc6070 - PKCS #5: Password-Based Key Derivation Function 2 (PBKDF2) Test Vectors
'https://en.wikipedia.org/wiki/PBKDF2

'DK = T1 || T2 || ... || Tdklen/hlen
'Ti = F(password, salt, c, i)
'
'F(Password, Salt, c, i) = U1 ^ U2 ^ ... ^ Uc
'
'U_1 = PRF (P, S || INT (i)) (INT (i) is a four-octet encoding of the integer i, most significant octet first.)
'U_2 = PRF (P, U_1)
'...
'U_c = PRF (P, U_{c-1})

Dim utf8Encoding As Object
Dim hashManager As Object

Dim hLen As Long
Dim noBlocks As Long
Dim noBlock As Long

Dim hmacKeyBytes() As Byte
Dim saltBytes() As Byte
Dim uboundSaltBytes As Long

Dim hmacBytes() As Byte
Dim tempBytes() As Byte
Dim outputBytes() As Byte

Dim i As Long
Dim j As Long

'Create utf8-encoding object
Set utf8Encoding = CreateObject("System.Text.UTF8Encoding")

'Create hmac object
Select Case algoritm
    Case HMAC_MD5
        Set hashManager = CreateObject("System.Security.Cryptography.HMACMD5")
    Case HMAC_SHA1
        Set hashManager = CreateObject("System.Security.Cryptography.HMACSHA1")
    Case HMAC_SHA256
        Set hashManager = CreateObject("System.Security.Cryptography.HMACSHA256")
    Case HMAC_SHA384
        Set hashManager = CreateObject("System.Security.Cryptography.HMACSHA384")
    Case HMAC_SHA512
        Set hashManager = CreateObject("System.Security.Cryptography.HMACSHA512")
End Select

'Check the length of the blocks to be generated
hLen = hashManager.HashSize / 8

'Calculate amount of blocks 'T'
If dkLen = 0 Then dkLen = hLen
noBlocks = Application.WorksheetFunction.Ceiling(dkLen / hLen, 1)

'Encode the key and salt to bytes
hmacKeyBytes = utf8Encoding.GetBytes_4(password)
saltBytes = utf8Encoding.GetBytes_4(salt)

'Set the key in the crypto class
hashManager.key = hmacKeyBytes

'Get the length of the salt, add 4 to concatenate INT(I)
uboundSaltBytes = UBound(saltBytes) + 4

'Loop T1 || T2 || ... || Tdklen/hlen
For i = 1 To noBlocks

    'Salt || INT(i)
    'INT (i) is a four-octet encoding of the integer i, most significant octet first.
    tempBytes = saltBytes
    ReDim Preserve tempBytes(uboundSaltBytes)
    noBlock = i

    'Calculate INT(i) of Salt || INT(i)
    For j = 3 To 0 Step -1
        tempBytes(uboundSaltBytes - j) = Int(noBlock / (255 ^ j))
        noBlock = noBlock - Int(noBlock / (255 ^ j)) * 255 ^ j
    Next j

    'Hash U1: Salt || INT(i)
    hmacBytes = hashManager.ComputeHash_2(tempBytes)
    tempBytes = hmacBytes

    'Hash, Xor: U1 ^ U2 ^ ... ^ Uc
    For j = 1 To hashIterations - 1
        hmacBytes = hashManager.ComputeHash_2(hmacBytes)
        tempBytes = XorBytes(tempBytes, hmacBytes)
    Next j

    'For the first block outputBytes() is empty
    If i = 1 Then
        outputBytes = tempBytes
    Else
        ConcatenateArrayInPlace outputBytes, tempBytes
    End If

Next i

'Extract the first dkLen octets to produce a derived key DK:
ReDim Preserve outputBytes(dkLen - 1)

'Base64, Hex, or Byte() output
If encodeHash = heBase64 Then
    PBKDF2 = Encode(outputBytes, edBase64)
ElseIf encodeHash = heHex Then
    PBKDF2 = Encode(outputBytes, edHex)
Else
    PBKDF2 = outputBytes
End If

Set hashManager = Nothing
Set utf8Encoding = Nothing

End Function
Function HMAC(ByVal plainText As String, _
    ByVal algoritm As hmacAlgorithm, _
    Optional ByVal key As String, _
    Optional ByVal decodeKey As keyDecoding = kdNone_String, _
    Optional ByVal encodeHash As hashEncoding = heBase64) As Variant

Dim hashManager As Object

Dim hashBytes() As Byte
Dim hmacKeyBytes() As Byte

'Create the specific hash manager based on the hash algoritm
Select Case algoritm
    Case HMAC_MD5
        Set hashManager = CreateObject("System.Security.Cryptography.HMACMD5") 'Returns 128 bits, 16 bytes
    Case HMAC_SHA1
        Set hashManager = CreateObject("System.Security.Cryptography.HMACSHA1") 'Returns 160 bits, 20 bytes
    Case HMAC_SHA256
        Set hashManager = CreateObject("System.Security.Cryptography.HMACSHA256") 'Returns 256 bits, 32 bytes
    Case HMAC_SHA384
        Set hashManager = CreateObject("System.Security.Cryptography.HMACSHA384") 'Returns 384 bits, 48 bytes
    Case HMAC_SHA512
        Set hashManager = CreateObject("System.Security.Cryptography.HMACSHA512") 'Returns 512 bits, 64 bytes
End Select

'Encode the plaintText to bytes
hashBytes = UTF8_GetBytes(plainText)

If key = vbNullString Then

    'Get the key generated by the hashManager
    hmacKeyBytes = hashManager.key

    'Calculate the hash
    hashBytes = hashManager.ComputeHash_2(hashBytes)

    'Return encoded result
    If encodeHash = heBase64 Then
        HMAC = "<Key>" & Encode(hmacKeyBytes, edBase64) & "<Key>" & vbCrLf & Encode(hashBytes, edBase64)
    ElseIf encodeHash = heHex Then
        HMAC = "<Key>" & Encode(hmacKeyBytes, edHex) & "<Key>" & vbCrLf & Encode(hashBytes, edHex)
    End If

Else

    'Decode and set the key
    Select Case decodeKey
    Case kdBase64
        hashManager.key = Decode(key, edBase64)
    Case kdHex
        hashManager.key = Decode(key, edHex)
    Case Else
        hashManager.key = UTF8_GetBytes(key)
    End Select

    'Calculate the hash
    hashBytes = hashManager.ComputeHash_2(hashBytes)

    'Return encoded result
    If encodeHash = heBase64 Then
        HMAC = Encode(hashBytes, edBase64)
    ElseIf encodeHash = heHex Then
        HMAC = Encode(hashBytes, edHex)
    End If

End If

Set hashManager = Nothing

End Function

如蒙协助,将不胜感激。在Excel中使用PBKDF2时,谷歌搜索不会出现太多问题。

您的
HMAC
函数中的整个部分缺少一些枚举定义:

Select Case decodeKey
Case kdBase64
    hashManager.key = Decode(key, edBase64)
Case kdHex
    hashManager.key = Decode(key, edHex)
Case Else
    hashManager.key = UTF8_GetBytes(key)
End Select
decodeKey
在函数签名中声明,类型为
keyDecoding
,我认为这是一个枚举:

Optional ByVal decodeKey As keyDecoding = kdNone_String
这就是导致错误的原因,这个
keydecking
enum在任何地方都没有定义。然而,它看起来只有3个成员,所以你可能可以推出自己的

Decode
Encode
功能同时使用
edBase64
edHex
成员进行一些枚举。这个枚举也没有在任何地方定义(虽然这不是导致错误的原因,但这是我提到的第一点)


您还没有包括这两个函数,所以我不能说更多,但我想它们的签名会告诉您第二个缺少的枚举的名称。代码可能还有其他问题,但这正是我所关注的。确保您从源代码处正确复制了它:)

您缺少了
密钥解码
枚举我认为在
ByVal decodeKey中,作为密钥解码
-要么您复制了错误的核心,要么它不存在,您需要自己编写感谢-我已经从源代码处处理了所有内容(重新检查)也许他们在发布时遗漏了它?(原始帖子中的链接)谢谢你的帮助,不过,我不太确定自己该怎么写\我快速浏览了一下SO post you链接;
Decode
功能未包含在内,因此您必须找到自己的功能。
Encode
函数在问题的主体中。枚举缺失,但不太难写入。我建议阅读
Decode
函数的功能,尝试编写自己的函数,如果您有困难,请在这里的新问题中发布。PS你只需要评论一次,就可以在帖子开始时标记某人做
@username
(请参阅添加评论框底部的帮助链接)谢谢-我已经从来源处处理了所有问题(重新检查)也许他们在帖子中遗漏了它?(原始帖子中的链接)谢谢你的帮助,不过,我不太确定自己该怎么写\