sockscape/server/Encryption/KeyExchange.cs

66 lines
2.3 KiB
C#
Raw Normal View History

2017-05-17 21:06:16 +00:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Numerics;
2017-07-22 19:27:41 +00:00
using Glove;
using System.Globalization;
using System.Security.Cryptography;
2017-05-17 21:06:16 +00:00
2017-07-22 19:27:41 +00:00
namespace SockScape.Encryption {
2017-05-26 20:28:02 +00:00
class Key {
public const int KeySize = 512;
public const int KeySizeBytes = KeySize / 8;
private static readonly BigInteger Secret = RNG.NextPrime(KeySizeBytes);
2017-08-21 21:03:32 +00:00
public BigInteger Generator { get; } = 2;
public BigInteger Modulus { get; }
2017-05-20 23:33:39 +00:00
public BigInteger PrivateKey { get; private set; } = BigInteger.Zero;
2017-08-21 21:03:32 +00:00
public bool Succeeded
=> !PrivateKey.IsZero;
2017-05-17 21:06:16 +00:00
2017-05-26 20:28:02 +00:00
public Key() {
Modulus = RNG.NextPrime(KeySizeBytes);
}
2017-05-18 21:03:35 +00:00
2017-05-20 23:33:39 +00:00
public Packet GenerateRequestPacket() {
2017-05-25 21:08:21 +00:00
return new Packet(
1,
2017-05-25 21:08:21 +00:00
Generator.ToHexString(),
Modulus.ToHexString(),
BigInteger.ModPow(Generator, Secret, Modulus).ToHexString()
);
2017-05-20 23:33:39 +00:00
}
public Packet ParseRequestPacket(Packet packet) {
if(packet.Id != 1 || packet.RegionCount != 3)
return null;
2017-08-21 21:03:32 +00:00
var check = BigInteger.TryParse(packet[0], NumberStyles.HexNumber,
NumberFormatInfo.InvariantInfo, out BigInteger generator);
check &= BigInteger.TryParse(packet[1], NumberStyles.HexNumber,
NumberFormatInfo.InvariantInfo, out BigInteger modulus);
check &= BigInteger.TryParse(packet[2], NumberStyles.HexNumber,
NumberFormatInfo.InvariantInfo, out BigInteger serverKey);
if(!check)
return null;
var clientKey = BigInteger.ModPow(generator, Secret, modulus);
PrivateKey = BigInteger.ModPow(serverKey, Secret, modulus);
return new Packet(1, clientKey.ToHexString());
}
2017-05-20 23:33:39 +00:00
public BigInteger ParseResponsePacket(Packet packet) {
if(packet.Id != 1 || packet.RegionCount != 1)
2017-05-20 23:33:39 +00:00
return -1;
2017-05-18 21:03:35 +00:00
if(!BigInteger.TryParse(packet[0], NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo, out BigInteger clientKey))
2017-05-20 23:33:39 +00:00
return -1;
2017-08-21 21:03:32 +00:00
return PrivateKey = BigInteger.ModPow(clientKey, Secret, Modulus);
2017-05-19 21:02:39 +00:00
}
2017-05-17 21:06:16 +00:00
}
}