我一直在试图解决为什么在Vista SP2机器上编写和编译VB6应用程序中的元素在该机器上完美工作,但没有在64位Windows 10机器上。为了提高调试功能,我在Excel VBA中复制了编码问题。适用于Vista机器,但不适用于Windows 10机器。VB代码使用advapi32.dll cryptverifysignature作品在Vista SP2不在Windows 10 64位
中的CryptoAPI电话都宣称正是如此:
Private Declare Function CryptVerifySignature _
Lib "advapi32.dll" _
Alias "CryptVerifySignatureA" (_
ByVal hHash As Long, _
pbSignature As Byte, _
ByVal dwSigLen As Long, _
ByVal hPubKey As Long, _
ByVal sDescription As String, _
ByVal dwFlags As Long _
) As Long
是在Windows 10的机器上失败的部分由上方和下方铁轨下面的高亮显示:
Private Function SignValidate(ByRef abData() As Byte, _
ByRef abSigned() As Byte, _
Optional bSigned As Boolean = True) As Long
Dim hHash As Long
Dim lngReturnValue As Long
Dim lngSigLen As Long
Dim abText() As Byte
Dim strTxt As String
Dim lngW As Long
Dim lngX As Long
Dim lngY As Long
Dim abHashVal() As Byte
SignValidate = -1
ReDim abText(UBound(abData))
abText = abData
'Create a hash object to sign/validate
lngReturnValue = CryptCreateHash(hCryptProv, CALG_SHA, 0, 0, hHash)
If lngReturnValue = 0 Then
'Set_locale regionalSymbol
Err.Raise Err.LastDllError, , "DLL error code shown above. Could not create a Hash Object (CryptCreateHash API)"
End If
'Hash the data
lngW = UBound(abText) + 1
lngReturnValue = CryptHashData(hHash, abText(0), lngW, 0)
If lngReturnValue = 0 Then
'Set_locale regionalSymbol
Err.Raise Err.LastDllError, , "DLL error code shown above. Could not calculate a Hash Value (CryptHashData API)"
End If
If bSigned Then
'release old key pair handle
If hKeyPair <> 0 Then CryptDestroyKey hKeyPair
'get a handle to the signature key pair
lngReturnValue = CryptGetUserKey(hCryptProv, AT_SIGNATURE, hKeyPair)
If lngReturnValue = 0 Then
'Set_locale regionalSymbol
Err.Raise Err.LastDllError, , "DLL error code shown above. Could not obtain key pair"
End If
'Determine the size of the signature
lngReturnValue = CryptSignHash(hHash, AT_SIGNATURE, 0, 0, vbNull, lngSigLength)
If lngSigLength > 0 Then ReDim abSig(lngSigLength - 1)
'Sign the hash object
lngReturnValue = CryptSignHash(hHash, AT_SIGNATURE, 0, 0, abSig(0), lngSigLength)
If lngReturnValue = 0 Then
'Set_locale regionalSymbol
Err.Raise Err.LastDllError, , "DLL error code shown above. Could not sign the hash"
End If
' the signature is now available
' size returned array to signature length
ReDim abSigned(UBound(abSig))
' return the signature to the calling procedure
abSigned = abSig
SignValidate = 0
Else
lngSigLength = UBound(abSigned) + 1
ReDim abSig(UBound(abSigned))
abSig = abSigned ' load the Signature array
'========================================================
'this is the line where the actual validation is done
lngReturnValue = CryptVerifySignature(hHash, abSig(0), lngSigLength, hKeyPair, 0, 0)
'========================================================
If lngReturnValue = 0 Then 'some error occurred
SignValidate = Err.LastDllError
Else
SignValidate = 0
End If
End If
End Function
在Windows 10机器突出显示的对CryptVerifySignature的调用失败,并返回等于NTE_BAD_SIGNATURE的Err.LastDllError。 Vista机器验证签名正常。
我花了几天的时间研究可能发生的事情。一切都无济于事。任何指针感激地接受
Vista机器是64位的吗? – dbugger
您可能需要使用条件编译属性。如果你有一个64位版本的办公室,VBA的版本不再是VBA6,而是VBA7。调用API /函数略有不同。从MS看到这篇文章。 https://msdn.microsoft.com/en-us/library/office/ee691831(v=office.14).aspx –
感谢您的回复。 Vista机器是32位的。 Vista机器上的Excel 2003,Windows 10机器上的32位Excel 2016。我相信在VBA中失败的那一行是在编译的VB6程序中失败的那一行,其中对CryptVerifySignature的调用位于一个自定义DLL中。 –