mysimulation/server/FSO.Server.Protocol/Utils/ChallengeResponse.cs
Tony Bark 22191ce648 Removed NioTSO client and server
- NioTSO client isn't needed because we're using RayLib
- Added FreeSO's API server to handle most backend operations
2024-05-01 02:55:43 -04:00

77 lines
2.6 KiB
C#
Executable file

using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
namespace FSO.Server.Protocol.Utils
{
public class ChallengeResponse
{
private static int _salt_byte_length = 320;
private static int _nonce_byte_length = 32;
private static RNGCryptoServiceProvider _random_crypt_prov = new RNGCryptoServiceProvider();
private static Random _random_gen = new Random();
private static int _min_iteration_count = 4000;
private static int _max_iteration_count = 5000;
private const int _sha_output_length = 20;
private static byte[] ComputeHMACHash(byte[] data, string secret)
{
using (var _hmac_sha_1 = new HMACSHA1(data, true))
{
byte[] _hash_bytes = _hmac_sha_1.ComputeHash(Encoding.UTF8.GetBytes(secret));
return _hash_bytes;
}
}
public static string AnswerChallenge(string challenge, string secret)
{
var components = new Dictionary<string, string>();
var parts = challenge.Split(',');
foreach(var part in parts){
var subParts = part.Split(new char[] { '=' }, 2);
components.Add(subParts[0], subParts[1]);
}
var iterations = int.Parse(components["i"]);
var salt = components["s"];
var salted = Hi(secret, Convert.FromBase64String(salt), iterations);
return Convert.ToBase64String(ComputeHMACHash(salted, secret));
}
public static string GetChallenge()
{
var numIterations = GetRandomInteger();
return "i=" + numIterations + ",s=" + Convert.ToBase64String(GetRandomByteArray(_nonce_byte_length));
}
private static byte[] Hi(string password, byte[] salt, int iteration_count)
{
Rfc2898DeriveBytes _pdb = new Rfc2898DeriveBytes(password, salt, iteration_count);
return _pdb.GetBytes(_sha_output_length);
}
private static int GetRandomInteger()
{
if (_random_gen == null)
_random_gen = new Random();
int _random_int = _random_gen.Next(_min_iteration_count, _max_iteration_count);
if (_random_int < 0)
_random_int *= -1;
return _random_int;
}
private static byte[] GetRandomByteArray(int byte_array_length)
{
byte[] _random_byte_array = new byte[byte_array_length];
_random_crypt_prov.GetBytes(_random_byte_array);
return _random_byte_array;
}
}
}