title: Can I use the RandomNumberGenerator.GetInt32() method to generate a cryptographically-secure random string?
body: <p>I've been trying to write a simple helper method in C# that generates a cryptographically-secure random string with any given length and character set. I know that you shouldn't use the <a href="https://docs.microsoft.com/en-us/dotnet/api/system.random?view=net-6.0" rel="nofollow noreferrer"><code>Random</code></a> class if you want cryptographic security. In the past, the <a href="https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.rngcryptoserviceprovider?view=net-6.0" rel="nofollow noreferrer"><code>RNGCryptoServiceProvider</code></a> class would always be suggested as an alternative to <code>Random</code> to provide cryptographic safety. That class is now obselete and <a href="https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.randomnumbergenerator" rel="nofollow noreferrer"><code>RandomNumberGenerator</code></a> is supposed to be used instead.</p>
  <p>Now, what I'm confused about is that many answers in <a href="https://stackoverflow.com/q/1344221/7734384">this famous question</a> that are using the new <code>RandomNumberGenerator</code> class — such as <a href="https://stackoverflow.com/a/1344255/7734384">this one</a> — are using the <code>GetBytes()</code> method, and then doing lots of other stuff afterwards to make things work; but I don't understand why they're not using <a href="https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.randomnumbergenerator.getint32?view=netcore-3.0" rel="nofollow noreferrer"><code>GetInt32()</code></a> instead and then using the result as an index in the character set? It seems like that would make this much simpler.</p>
  <p>This is what I'm talking about:</p>
  <pre><code>public string GenerateRandomString(int length, string charSet = &quot;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789&quot;)
  {
      char[] result = new char[length];
  
      for (int i = 0; i &lt; length; i++)
          result[i] = charSet[RandomNumberGenerator.GetInt32(charSet.Length)];
  
      return new string(result);
  }
  </code></pre>
  <p>My question is this: <strong>Is this way of generating random strings cryptographically sound or not?</strong> The fact that I never saw this being done makes me uncertain, which is why I'm asking this question. And if it isn't, could you please explain why?</p>
  <p>Thank you.</p>