1
因此,一段時間以來,我通過使用Microsoft強密碼提供程序的MS API調用實現了我自己的MS Access VBA密碼安全僞隨機數生成器(CSPRNG)。它以密碼安全的方式吐出隨機字節0-255(00000000-11111111)。該調用是通過VBA模塊中的幾個DLL函數聲明(調用「advapi32.dll」)完成的。爲什麼CryptAcquireContext在某些計算機上一直返回0(零)?
這裏的問題是,我撥打CryptAcquireContext(...)
的電話不是給我一個加密上下文....但只在一些電腦。它在我建立的機器上工作得很好......但不在其他人的機器上。這不是一個VBE參考問題;該DLL存在,並且模塊中的任何調用都不依賴於VBE引用。我嘗試了其他幾家「提供商......」不好。全零。
下面的代碼:
Option Compare Database
Option Explicit
Private Const MS_STRONG_PROV = "Microsoft Strong Cryptographic Provider"
Private Const PROV_RSA_FULL = 1 Private Const CRYPT_VERIFYCONTEXT = 0
#If VBA7 Then
Private Declare PtrSafe Function CryptAcquireContext Lib "advapi32.dll" Alias "CryptAcquireContextA" _
(ByRef phProv As Long, ByVal pszContainer As String, ByVal pszProvider As String, _
ByVal dwProvType As Long, ByVal dwFlags As Long) As Boolean '
Private Declare PtrSafe Function CryptGenRandom Lib "advapi32.dll" _
(ByVal hProv As Long, ByVal dwLen As Long, ByRef pbBuffer As Byte) As Boolean
Private Declare PtrSafe Function CryptReleaseContext Lib "advapi32.dll" _
(ByRef hProv As Long, ByVal dwFlagas As Long)
#Else
Private Declare Function CryptAcquireContext Lib "advapi32.dll" Alias "CryptAcquireContextA" _
(ByRef phProv As Long, ByVal pszContainer As String, ByVal pszProvider As String, _
ByVal dwProvType As Long, ByVal dwFlags As Long) As Boolean '
Private Declare Function CryptGenRandom Lib "advapi32.dll" _
(ByVal hProv As Long, ByVal dwLen As Long, ByRef pbBuffer As Byte) As Boolean
Private Declare Function CryptReleaseContext Lib "advapi32.dll" _
(ByRef hProv As Long, ByVal dwFlagas As Long)
#End If
Public Function RandomByte() As Byte
On Error Resume Next
Dim lngContext As Long, bytResult As Byte
' Supposed to dump a value into lngContext... only spitting out zero.
Call CryptAcquireContext(lngContext, vbNullString, MS_STRONG_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)
' Which means THIS ALSO spits out only a zero....
Call CryptGenRandom(lngContext, 1, bytResult)
'...and this is crashing for unknown reasons.
Call CryptReleaseContext(lngContext, 0)
RandomByte = bytResult
End Function
你的API聲明不正確。如果你使用'Long'而不是'LongPtr'作爲指針變量,它將在64位執行上下文中失敗。 – Comintern
它在*我的* 64位機器上工作得很好... –
您是否檢查過失敗時的返回值?你現在只是放棄它們。另外,您的Access安裝32位? – Comintern