Partager via


Cryptographically Secure Random number on Windows without using CryptoAPI

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 following snippet shows how to call the function.

HMODULE hLib=LoadLibrary("ADVAPI32.DLL");
if (hLib) {
BOOLEAN (APIENTRY *pfn)(void*, ULONG) =
      (BOOLEAN (APIENTRY *)(void*,ULONG))GetProcAddress(hLib,"SystemFunction036");
if (pfn) {
char buff[32];
ULONG ulCbBuff = sizeof(buff);
if(pfn(buff,ulCbBuff)) {

   // use buff full of random goop

}
}

 FreeLibrary(hLib);
}

The good news is you can get good random numbers, without the memory overhead of pulling in all of CryptoAPI!

RtlGenRandom is documented at https://msdn.microsoft.com/library/en-us/seccrypto/security/rtlgenrandom.asp.

Comments

  • Anonymous
    January 14, 2005
    So, it is available in w2k, nice. Can you give a details on what is behind RtlGenRandom, how does it works? Something like SHA1/MD5 against the pool of entropy collected from the system events.

  • Anonymous
    January 14, 2005
    The comment has been removed

  • Anonymous
    January 14, 2005
    hmm, I don't see a SystemFunction036 on my Win 2K's advapi32.dll. The numbers skip from 035 to 040.

  • Anonymous
    January 14, 2005
    Nice. Thanks, Michael

  • Anonymous
    January 15, 2005
    Did you run the code on Windows 2000? Which service pack are you using? If you still have noy joy I'll look at it on monday.

  • Anonymous
    January 15, 2005
    I like the fact that the parameters are called "RandomBuffer" and "RandomBufferLength." Maybe I should write:

    char *buff = new char[rand()];
    RtlGenRandom(buff, rand());

    <ducks>

  • Anonymous
    January 17, 2005
    The comment has been removed

  • Anonymous
    January 17, 2005
    Here's the info: Win2K pro SP3, advapi32.dll is version 5.0.2195.5385 and it doesn't have an export SystemFunction036.

  • Anonymous
    January 19, 2005
    Also on SP4+all recent security updates, dll version 5.00.2195.6876, as far as I can see there's no SystemFunction036. There is 035 and then 040.

  • Anonymous
    January 20, 2005
    So I stand corrected - this is in WinXP and later... sincere apologies for the mixup. The MSDN docs are correct, and I am wrong.

  • Anonymous
    April 08, 2005
    El uso de los numeros al azar es importante, si es para un juego, la clase Random esta bien, pero si...

  • Anonymous
    June 15, 2007
    PingBack from http://agraja.wordpress.com/2007/06/16/links-for-2007-06-16/

  • Anonymous
    May 26, 2008
    PingBack from http://appzdrive.com/home/8/?p=77860

  • Anonymous
    January 20, 2009
    PingBack from http://www.hilpers-esp.com/439873-generar-numeros-al-azar

  • Anonymous
    June 18, 2009
    PingBack from http://www2.orourkes.us:11080/blog/2009/06/18/https-dissected/