1
0
mirror of https://github.com/bitwarden/server.git synced 2025-01-11 20:10:38 +01:00

random string helper

This commit is contained in:
Kyle Spearrin 2017-06-29 15:55:39 -04:00
parent a1008353fd
commit 14745fa6ce

View File

@ -4,7 +4,10 @@ using Dapper;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data; using System.Data;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
namespace Bit.Core.Utilities namespace Bit.Core.Utilities
@ -124,5 +127,82 @@ namespace Bit.Core.Utilities
{ {
return globalSettings.U2f.AppId; return globalSettings.U2f.AppId;
} }
public static string SecureRandomString(int length, bool alpha = true, bool upper = true, bool lower = true,
bool numeric = true, bool special = false)
{
var characters = string.Empty;
if(alpha)
{
if(upper)
{
characters += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
}
if(lower)
{
characters += "abcdefghijklmnopqrstuvwxyz";
}
}
if(numeric)
{
characters += "0123456789";
}
if(special)
{
characters += "!@#$%^*&";
}
return SecureRandomString(length, characters);
}
// ref https://stackoverflow.com/a/8996788/1090359 with modifications
public static string SecureRandomString(int length, string characters)
{
if(length < 0)
{
throw new ArgumentOutOfRangeException(nameof(length), "length cannot be less than zero.");
}
if((characters?.Length ?? 0) == 0)
{
throw new ArgumentOutOfRangeException(nameof(characters), "characters invalid.");
}
const int byteSize = 0x100;
if(byteSize < characters.Length)
{
throw new ArgumentException(
string.Format("{0} may contain no more than {1} characters.", nameof(characters), byteSize),
nameof(characters));
}
var outOfRangeStart = byteSize - (byteSize % characters.Length);
using(var rng = RandomNumberGenerator.Create())
{
var sb = new StringBuilder();
var buffer = new byte[128];
while(sb.Length < length)
{
rng.GetBytes(buffer);
for(var i = 0; i < buffer.Length && sb.Length < length; ++i)
{
// Divide the byte into charSet-sized groups. If the random value falls into the last group and the
// last group is too small to choose from the entire allowedCharSet, ignore the value in order to
// avoid biasing the result.
if(outOfRangeStart <= buffer[i])
{
continue;
}
sb.Append(characters[buffer[i] % characters.Length]);
}
}
return sb.ToString();
}
}
} }
} }