How to access an already made P/Invoke declaration ?

This topic contains 2 replies, has 2 voices, and was last updated by Profile photo of NovHak NovHak 1 year, 9 months ago.

  • Author
  • #24564
    Profile photo of NovHak

    Dear forum readers,

    I am really, really new to Powershell. I started the whole thing very recently, when I realised that %random% used in .bat files was a very poor random generator. I won't go through the whole thing, so said shortly, it seems to me that the best random number generators in Windows (Windows 8.1 at least) are the ones available through the CNG API. The BCryptGenRandom function is used for this, and requires a pointer to an algorithm specified via BCryptOpenAlgorithmProvider. I didn't find any PowerShell/.NET counterpart of this, so I decided to do something which seems to be referred to as "P/Invoke" by knowing people.

    Unfortunately, I don't know how to convert the WINAPI types to types useable by PowerShell, and didn't help me, since they don't document those BCrypt* functions... but fortunately I found this : which indicates a P/Invoke declaration is already made for BCryptOpenAlgorithmProvider. Accessing that declaration would help me much in designing a P/Invoke for BCryptGenRandom.

    The problem is, all this looks terribly fuzzy for me right now, like a gas factory as we say in France to designate something overly complicated. Undoubtedly that's because I'm still a noob, so I have two questions : how can I access those win32 function already P/Invoked, with its parameter and output types ? I suppose it must be something like []::FunctionName but I've been unable to find it with the information provided at the previously given URL.

    An answer to the second question would be a bonus, but the question is more straightforward : what P/Invoke definition should I make to get access to BCryptGenRandom and BCryptOpenAlgorithmProvider ?

    Thanks for your help !

  • #24573
    Profile photo of TomBaker

    Get-Random for simple random values in powershell.

    If you need to use BCryptOpenAlgorithmProvider try the example

  • #24587
    Profile photo of NovHak

    Thanks Tom for your reply, but you're forcing me to go into more detail here !

    Of course I noticed Get-Random before thinking about P/Invoking BCryptGenRandom, since I tried the shortest path first 🙂 But there are issues with this function as it's too much predictable. This article despite lacking a complete formal analysis, addresses the issue. RNGCryptoServiceProvider, which is proposed as a replacement, uses the old CryptoAPI which is going to be replaced by the CNG API, and the algorithm behind it is 1) not publicly disclosed by Microsoft and 2) is known to be based on the SHA1 hash algorithm which has now been at least partially broken. As an example, RNGCryptoServiceProvider used to be the recommended way to generate random passwords, but that was ten years ago...

    The link you gave me doesn't point to some example code for BCryptGenRandom, but RNGCryptoServiceProvider which is easier to use since it's available in .NET, but is not what I want for the reasons above. Too bad MS didn't include BCryptGenRandom in their .NET specification yet. This method for generating random numbers uses algorithms based on the NIST SP 800-90A specification, which are well-known and stronger.

    So the question remains : how shall I P/Invoke BCryptGenRandom and BCryptOpenAlgorithmProvider ?

    Thanks for your help !

You must be logged in to reply to this topic.