Better session ID generation code.
This commit is contained in:
parent
8050a295c1
commit
dbdaaeec9e
3 changed files with 60 additions and 24 deletions
|
@ -4,7 +4,7 @@ using System.Collections.Generic;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
|
||||||
namespace SharpChat {
|
namespace SharpChat {
|
||||||
public class ChatUserSession : IDisposable, IPacketTarget {
|
public class ChatUserSession : IDisposable {
|
||||||
public const int ID_LENGTH = 32;
|
public const int ID_LENGTH = 32;
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
@ -22,9 +22,6 @@ namespace SharpChat {
|
||||||
|
|
||||||
private int CloseCode { get; set; } = 1000;
|
private int CloseCode { get; set; } = 1000;
|
||||||
|
|
||||||
public string TargetName => "@log";
|
|
||||||
|
|
||||||
|
|
||||||
private IPAddress _RemoteAddress = null;
|
private IPAddress _RemoteAddress = null;
|
||||||
|
|
||||||
public IPAddress RemoteAddress {
|
public IPAddress RemoteAddress {
|
||||||
|
@ -44,13 +41,7 @@ namespace SharpChat {
|
||||||
|
|
||||||
public ChatUserSession(IWebSocketConnection ws) {
|
public ChatUserSession(IWebSocketConnection ws) {
|
||||||
Connection = ws;
|
Connection = ws;
|
||||||
Id = GenerateId();
|
Id = RNG.SecureRandomString(ID_LENGTH);
|
||||||
}
|
|
||||||
|
|
||||||
private static string GenerateId() {
|
|
||||||
byte[] buffer = new byte[ID_LENGTH];
|
|
||||||
RNG.NextBytes(buffer);
|
|
||||||
return buffer.GetIdString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Send(IServerPacket packet) {
|
public void Send(IServerPacket packet) {
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace SharpChat {
|
|
||||||
public static class Extensions {
|
|
||||||
public static string GetIdString(this byte[] buffer) {
|
|
||||||
const string id_chars = "abcdefghijklmnopqrstuvwxyz0123456789-_ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
||||||
StringBuilder sb = new();
|
|
||||||
foreach(byte b in buffer)
|
|
||||||
sb.Append(id_chars[b % id_chars.Length]);
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +1,11 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
namespace SharpChat {
|
namespace SharpChat {
|
||||||
public static class RNG {
|
public static class RNG {
|
||||||
|
public const string CHARS = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789";
|
||||||
|
|
||||||
private static Random NormalRandom { get; } = new();
|
private static Random NormalRandom { get; } = new();
|
||||||
private static RandomNumberGenerator SecureRandom { get; } = RandomNumberGenerator.Create();
|
private static RandomNumberGenerator SecureRandom { get; } = RandomNumberGenerator.Create();
|
||||||
|
|
||||||
|
@ -21,5 +24,60 @@ namespace SharpChat {
|
||||||
public static void NextBytes(byte[] buffer) {
|
public static void NextBytes(byte[] buffer) {
|
||||||
SecureRandom.GetBytes(buffer);
|
SecureRandom.GetBytes(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int SecureNext() {
|
||||||
|
return SecureNext(int.MaxValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int SecureNext(int max) {
|
||||||
|
return SecureNext(0, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int SecureNext(int min, int max) {
|
||||||
|
--max;
|
||||||
|
if(min == max)
|
||||||
|
return min;
|
||||||
|
|
||||||
|
uint umax = (uint)max - (uint)min;
|
||||||
|
uint num;
|
||||||
|
|
||||||
|
byte[] buffer = ArrayPool<byte>.Shared.Rent(4);
|
||||||
|
try {
|
||||||
|
SecureRandom.GetBytes(buffer);
|
||||||
|
num = BitConverter.ToUInt32(buffer);
|
||||||
|
|
||||||
|
if(umax != uint.MaxValue) {
|
||||||
|
++umax;
|
||||||
|
|
||||||
|
if((umax & (umax - 1)) != 0) {
|
||||||
|
uint limit = uint.MaxValue - (uint.MaxValue & umax) - 1;
|
||||||
|
|
||||||
|
while(num > limit) {
|
||||||
|
SecureRandom.GetBytes(buffer);
|
||||||
|
num = BitConverter.ToUInt32(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
ArrayPool<byte>.Shared.Return(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int)((num % umax) + min);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string RandomStringInternal(Func<int, int> next, int length) {
|
||||||
|
char[] str = new char[length];
|
||||||
|
for(int i = 0; i < length; ++i)
|
||||||
|
str[i] = CHARS[next(CHARS.Length)];
|
||||||
|
return new string(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string RandomString(int length) {
|
||||||
|
return RandomStringInternal(Next, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string SecureRandomString(int length) {
|
||||||
|
return RandomStringInternal(SecureNext, length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue