Results 1 to 2 of 2

Thread: Possible fix to the improved random generator technique I previously described

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Oct 2008
    Posts
    1,238

    Possible fix to the improved random generator technique I previously described

    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.

    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
    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.
    Code:
    Private Declare Function RtlGenRandom Lib "advapi32.dll" Alias "SystemFunction036" (ByRef RandomBuffer As Any, ByVal RandomBufferLength As Long) As Long
    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.

  2. #2
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: Possible fix to the improved random generator technique I previously described

    RtlGenRandom is not going away, and is actually the preferred way to call this for arbitrary uses instead of using the CryptoAPI wrapper call.

    We already established this in the other thread (why are there two?) by providing a link to an article by an authoritative source at Microsoft. Here it is once more:

    Cryptographically Secure Random number on Windows without using CryptoAPI

    Michael Howard January 14, 2005

    Historically, we always told developers not to use functions such as rand to generate keys, nonces and passwords, rather they should use functions like CryptGenRandom, which creates cryptographically secure random numbers. The problem with CryptGenRandom is you need to pull in CryptoAPI (CryptAcquireContext and such) which is fine if you’re using other crypto functions.

    On a default Windows XP and later install, CryptGenRandom calls into a function named ADVAPI32!RtlGenRandom, which does not require you load all the CryptAPI stuff. In fact, the new Whidbey CRT function, rand_s calls RtlGenRandom.

    The good news is you can get good random numbers, without the memory overhead of pulling in all of CryptoAPI!
    Stop beating a long dead horse.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width