In this thread http://www.vbforums.com/showthread.p...than-using-Rnd I mentioned gave a description of how to use CryptGenRandom to generate completely secure random numbers. However one person there said it didn't work for them. I have finally figured out how to fix the problem (I think, as I can't duplicate the problem they had, on my own computer). I posted an explanation in that thread, saying how to fix it, but not a single reply even acknowledging that I had posted a fix. None at all, it's like the method for fixing it is being ignored by the very person who was asking for a fix.
Therefore, I've created this new thread, and posted this complete fixed copy of the code in this thread (not merely instructions on how to fix it). Again, copy and paste this code into your form, and make sure that your form's AutoRedraw property is set to True.
The key here is that the dwFlags argument in the CryptGenRandom function has been set to CRYPT_VERIFYCONTEXT this time (rather than 0).
Again the pszProvider argument of the function is set to vbNullString, to use the default provider. And also again, if the default doesn't work, use one of the constants BaseProvider, EnhancedProvider, or StrongProvider for the pszProvider argument.
If NONE of these still work. Try starting VB6 as an administrator (not a standard user), and again repeat the above procedures for testing it.
If after all of this still does not work, I can't figure out what is wrong, because I believe I have exhausted all possible fixes.
In that case, I would recommend a shortcut for using the random number generator in the crypto API. That shortcut is to use RtlGenRandom, which is declared in the code box below.
It does not require a crypto provider handle (hProv) like CryptGenRandom does, so if you are having problems with CryptAcquireContext, RtlGenRandom will still work. However, that is an absolute last resort, as the MSDN documentation for RtlGenRandom https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx says that there is absolutely no guaranty that RtlGenRandom will be kept in future versions of Windows, and that one should instead use CryptGenRandom. That is why I am not suggesting you just switch over to using RtlGenRandom, but am instead trying to fix the code for using CryptGenRandom, and would suggest that RtlGenRandom be used ONLY if ALL ELSE fails.
Therefore, I've created this new thread, and posted this complete fixed copy of the code in this thread (not merely instructions on how to fix it). Again, copy and paste this code into your form, and make sure that your form's AutoRedraw property is set to True.
Code:
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 Long
Private Declare Function CryptReleaseContext Lib "advapi32.dll" (ByVal hProv As Long, ByVal dwFlags As Long) As Long
Private Declare Function CryptGenRandom Lib "advapi32.dll" (ByVal hProv As Long, ByVal dwLen As Long, ByRef pbBuffer As Any) As Long
Private Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)
Private Const BaseProvider As String = "Microsoft Base Cryptographic Provider v1.0"
Private Const EnhancedProvider As String = "Microsoft Enhanced Cryptographic Provider v1.0"
Private Const StrongProvider As String = "Microsoft Strong Cryptographic Provider"
Private Const CRYPT_VERIFYCONTEXT As Long = &HF0000000
Dim hProv As Long
Dim Quit As Boolean
Private Sub Form_Load()
Dim a As Long
CryptAcquireContext hProv, vbNullString, vbNullString, 1, CRYPT_VERIFYCONTEXT
If hProv = 0 Then
Unload Me
Exit Sub
End If
Show
Do Until Quit
CryptGenRandom hProv, 4, a
Cls
Print a
Sleep 100
DoEvents
Loop
End Sub
Private Sub Form_Unload(Cancel As Integer)
Quit = True
If hProv Then CryptReleaseContext hProv, 0
End Sub
Again the pszProvider argument of the function is set to vbNullString, to use the default provider. And also again, if the default doesn't work, use one of the constants BaseProvider, EnhancedProvider, or StrongProvider for the pszProvider argument.
If NONE of these still work. Try starting VB6 as an administrator (not a standard user), and again repeat the above procedures for testing it.
If after all of this still does not work, I can't figure out what is wrong, because I believe I have exhausted all possible fixes.
In that case, I would recommend a shortcut for using the random number generator in the crypto API. That shortcut is to use RtlGenRandom, which is declared in the code box below.
Code:
Private Declare Function RtlGenRandom Lib "advapi32.dll" Alias "SystemFunction036" (ByRef RandomBuffer As Any, ByVal RandomBufferLength As Long) As Long