using System; using System.Runtime.InteropServices; using System.ComponentModel; namespace JavaScienceCrypto{ public class Win32 { /* BOOL WINAPI CryptGenRandom( HCRYPTPROV hProv, DWORD dwLen, BYTE* pbBuffer ); */ [DllImport("advapi32.dll", SetLastError=true)] public static extern bool CryptGenRandom( IntPtr hProv, uint dwLen, [In, Out] IntPtr pbBuffer) ; /*BOOL WINAPI CryptAcquireContext( HCRYPTPROV* phProv, LPCTSTR pszContainer, LPCTSTR pszProvider, DWORD dwProvType, DWORD dwFlags); */ [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)] public static extern bool CryptAcquireContext( ref IntPtr hProv, string pszContainer, string pszProvider, uint dwProvType, uint dwFlags) ; /*BOOL WINAPI CryptReleaseContext( HCRYPTPROV hProv, DWORD dwFlags); */ [DllImport("advapi32.dll", SetLastError=true)] public static extern bool CryptReleaseContext( IntPtr hProv, uint dwFlags) ; } public class RandomIntPtr { const String title = "RandomIntPtr"; const uint PROV_RSA_FULL = 0x00000001; const uint CRYPT_VERIFYCONTEXT = 0xF0000000; //no private key access required public static void Main() { String[] args = Environment.GetCommandLineArgs(); if(args.Length<2){ Console.WriteLine("Usage: {0} [int from 5 to 5000]", title); return; } String fname = args[1]; int numbytes=0; try{ numbytes = Int32.Parse(args[1]); } catch(FormatException fexc){ Console.WriteLine("Argument not a valid integer"); return; } catch(Exception exc){ Console.WriteLine("Problem parsing argument {0}\n{1}", args[1], exc); return; } byte[] ranbytes = GenCryptRandomNumber(numbytes) ; if(ranbytes == null) { Console.WriteLine("Couldn't get random bytes"); return; } Console.WriteLine("------------- Random Bytes[{0}]: ----------------------", numbytes); for(int i=1; i<=ranbytes.Length; i++){ Console.Write("{0:x2} ", ranbytes[i-1]) ; if(i%16 == 0) Console.WriteLine(""); } Console.WriteLine("\n-------------------------------------------------------"); } private static byte[] GenCryptRandomNumber(int ranbytes){ if(ranbytes<5 || ranbytes>5000) //limit range return null; String provider = null ; //can use null, for default provider String container = null; //required for crypt_verifycontext uint type = PROV_RSA_FULL ; uint flags = CRYPT_VERIFYCONTEXT ; //no private key access required IntPtr hProv = IntPtr.Zero; bool gotcsp = Win32.CryptAcquireContext(ref hProv, container, provider, type, flags); if (!gotcsp){ showWin32Error(Marshal.GetLastWin32Error()); return null ; } else Console.WriteLine("Got handle to CSP: hProv 0x{0:X}", hProv.ToInt32()); IntPtr pRanbytes = Marshal.AllocHGlobal(ranbytes); if(!Win32.CryptGenRandom(hProv, (uint)ranbytes, pRanbytes)){ showWin32Error(Marshal.GetLastWin32Error()); Console.WriteLine("Failed to get random bytes!"); } Console.WriteLine("pRanbytes {0}", pRanbytes); byte[] randata = new byte[ranbytes]; Marshal.Copy(pRanbytes, randata, 0, ranbytes); Marshal.FreeHGlobal(pRanbytes); if (hProv != IntPtr.Zero) Win32.CryptReleaseContext(hProv,0) ; return randata ; } private static void showWin32Error(int errorcode){ Win32Exception myEx=new Win32Exception(errorcode); Console.WriteLine("Error code:\t 0x{0:X}", myEx.ErrorCode); Console.WriteLine("Error message:\t " + myEx.Message); } } }