65 lines
2.3 KiB
C#
65 lines
2.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Numerics;
|
|
using Glove;
|
|
using System.Globalization;
|
|
using System.Security.Cryptography;
|
|
|
|
namespace SockScape.Encryption {
|
|
class Key {
|
|
public const int KeySize = 512;
|
|
public const int KeySizeBytes = KeySize / 8;
|
|
|
|
private static readonly BigInteger Secret = RNG.NextPrime(KeySizeBytes);
|
|
public BigInteger Generator { get; } = 2;
|
|
public BigInteger Modulus { get; }
|
|
public BigInteger PrivateKey { get; private set; } = BigInteger.Zero;
|
|
public bool Succeeded
|
|
=> !PrivateKey.IsZero;
|
|
|
|
public Key() {
|
|
Modulus = RNG.NextPrime(KeySizeBytes);
|
|
}
|
|
|
|
public Packet GenerateRequestPacket() {
|
|
return new Packet(
|
|
1,
|
|
Generator.ToHexString(),
|
|
Modulus.ToHexString(),
|
|
BigInteger.ModPow(Generator, Secret, Modulus).ToHexString()
|
|
);
|
|
}
|
|
|
|
public Packet ParseRequestPacket(Packet packet) {
|
|
if(packet.Id != 1 || packet.RegionCount != 3)
|
|
return null;
|
|
|
|
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());
|
|
}
|
|
|
|
public BigInteger ParseResponsePacket(Packet packet) {
|
|
if(packet.Id != 1 || packet.RegionCount != 1)
|
|
return -1;
|
|
|
|
if(!BigInteger.TryParse(packet[0], NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo, out BigInteger clientKey))
|
|
return -1;
|
|
|
|
return PrivateKey = BigInteger.ModPow(clientKey, Secret, Modulus);
|
|
}
|
|
}
|
|
}
|