I'm using this code to generate random strings with given length
public string RandomString(int length)
{
const string valid = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
StringBuilder res = new StringBuilder();
Random rnd = new Random();
while (0 < length--)
{
res.Append(valid[rnd.Next(valid.Length)]);
}
return res.ToString();
}
However, I read that RNGCryptoServiceProvider
is more secure than Random
class. How can I implement RNGCryptoServiceProvider
to this function. It should use valid
string just like this function.
The
RNGCryptoServiceProvider
returns random numbers in the form of bytes, so you need a way to get a more convenient random number from it:Then you can use that in your method:
(I made the method static, as it doesn't use any instance data.)
note: I am aware of OP's use-case deviation, but I think it might help others who have a slightly different use-case
A lot can be said about the reasons to convert a cryptographic byte array into a string, but usually it is for some sort of serialization purposes; and hence, in that case: the selected character set is arbitrary.
So, if, and only if the former is true AND the length of the string doesn't required to be optimized; you can use a simple hexadecimal representation of the byte array like this:
Now you'll say: but wait: these are only 16 characters where OP's sequence has 62. Your string will be a lot longer.
"Yes", I will answer, "and if that's a problem, why don't you pick 256 easy-to-read-and-serrializable-characters... or perhaps 64" ;-)
As @Guffa stated; using
%
is forbidden unless it doesn't alter the distribution. To make this happen, given a evenly distributed set, the subset must fit exactly x times in the original set.So, expanding your initial valid set with 2 gives a valid result (because: 256 / 64 = 4).
The code would be:
Please note: in all the answers, including this one, the sub-set is smaller than the 256 possibilities of the byte. This means there is less information available. This means if you have your string with 4 chars, it's easier to crack the original 4 byte result of the RNGCryptoServiceProvider.
So... now you say: "Why not use 64 base encoding?", well, if it's suits you, but be careful with the trailing
=
, see Base64 on Wikipedia:Please note²: A typical use case is some url token. Please note that the
+
sign is invalid as such a character.