我一直在試圖解決爲什麼在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中。 –