Authentication
Note
This is part of the Low Level Transport for advanced users only.
To prevent MITM attacks, you can use authentication to make sure the peer you're connecting to is actually who they say they are. The only caveat with this is that you need to create a cryptographic key pair in advance and hardcode the public key into the code of the clients.
Generating a new key pair
Before you do any authentication, you need to generate a new RSA key pair:
CryptoRSA rsa = new CryptoRSA();
Console.WriteLine("PrivateKey = " + rsa.ExportPrivateKey());
Console.WriteLine("PublicKey = " + rsa.ExportPublicKey());
or if you're using Unity:
public class KeyGenerator : MonoBehaviour {
public void Start() {
CryptoRSA rsa = new CryptoRSA();
Debug.Log("PrivateKey = " + rsa.ExportPrivateKey());
Debug.Log("PublicKey = " + rsa.ExportPublicKey());
}
}
Example private key:
VcuIthN8WRB16cAGekL29SUmeCIX7Lo6CCezzr70VIK2iOefsT22CizUcXolmKnvxtO4nHHm0uZ5JrniWiYtS2iNg3DoWv7dwNRd5D/4ER04odinu1nr9Hn6OVN3Mm/ZCxoe0cDkHg9fh0KyyFet/K1BTsVi+8xH6u3vz0Ax/vHRfaEYF5k+cYqV58pvn12xxsG3D8lFHtkT/3uszxOEwbvvWDtvys1elde4Bd4qeyYE6chglGsao0oHhzzC9sLXc+di6njKcGVi9vIgbjZ7pgAb6FJADZlhAtWwdVe2phE2BlDsEEc3cPt6okj3oQUTcApiTBslq0q8vsdlu3WgUWMBqXLmpsdqJ2Qe8PGzUIaYdq9j3Jxd8ZC+P2QDy81FkfkbZjr0Er7wFLLO7Of+9a1KgcB/jJ932SWDZ6Zl3qHgA3LTQJYa0Y7oDihDzVLnseektyzIa+0DXym1Dgon9qcgpqlHpC+UKJ4ogtsoi+SzUmaLT7k8Jg10H9HE9+6piuRHI9Elg9EJVVmOtdeBapzyCukjzjPxPxHW/XYiA+zbheF1746KTNDks+TM5SaQDDBZSrea1dtlzL6ZUY21Smf56ErYYeB2NZQafSwY18G6m6bRiV2RTBpI04rg3/0QzrH3aFo+pxewRFYuxNvdI2SlYNI4povpX/HkAe9BiykBIm0siIkdqLiK/NHUOqBSAtQ5vgiFrw5SgLOPlTns7QgT/7Meej8uuM+aGc27XCNHT+zQ/9DixUeqRjyq+V4AdUsFhIZhHgeNA+ksyXqkxtYM8BIzUfvUaPHUUUxe+O/I2sb9+EKXD1jEvQVLVlEKAKe6Yc6TrLnSQIju56yzHdxGgkXNwk6iqPNSnwCi4g32IKrRxFXzMMjrCf5NfqkozvRT7bc+ZKZZfB8yMiINw6IVYEzOoUYyJT1ZAhD5b3pka2Pu3lJZqquY45/HzPu9leJJd9iz9AeFZIDo1plvGI98hOclL6rUJi07pyIu9YNkaPvVvEGKxz+Aifh/lM0y0lh1qm+4BbEMdFTWeMKrnXsgb8PU1L5JYNS316+hlzCJShgBa08KKvSzMqLYQRmB16MqKDqxNT7njt51GkeqMJti+mhIhc91iC/pVLkJZ4MIv5klkGkD51nSSZmOT3QfUmryGPInq5R3elyPAi98NJyJ3qomZCcB8/FjXNgWefPnuAAKrdOyjkdBwPcQlhlJWQnanQbJHYKqqjqj95ZmJjUfVW/eAxZaUHK0yvROcFrNe1ss3RGZUa6cOh5U//ReaIaZZPFd2TKJHHqCKpSj8oN1dvdBZk7IR+62evqGl3BZcOLRRI/IDYhCIHIg1VV0ViXdpBYzx8AqXdjjgHaplfNbiM1h4YlI1Hy/jjfWG8ZHUigZ8cJ0kQIFBietNYkfV7TbiGzhbtESGz7JAWjZaC/3fveL9ehxo3exom1kDdp5oxXMCyW0HLtv46V7l6qMIWG3psDH7FrcTpx0w8NttD80W9ZmDcCVhwW2DJ03H4FsD7JpWxZz6aHYqMbHDYNn
Example public key generated with the above private key:
3EaCRc3CTqKo81KfAKLiDfYgqtHEVfMwyOsJ/k1+qSjO9FPttz5kpll8HzIyIg3DohVgTM6hRjIlPVkCEPlvemRrY+7eUlmqq5jjn8fM+72V4kl32LP0B4VkgOjWmW8Yj3yE5yUvqtQmLTunIi71g2Ro+9W8QYrHP4CJ+H+UzTLSWHWqb7gFsQx0VNZ4wqudeyBvw9TUvklg1LfXr6GXMIlKGAFrTwoq9LMyothBGYHXoyooOrE1PueO3nUaR6owm2L6aEiFz3WIL+lUuQlngwi/mSWQaQPnWdJJmY5PdB9SavIY8ierlHd6XI8CL3w0nIneqiZkJwHz8WNc2BZ58w==
Once you have both the public key and the private key, you can then create a secure host using the private key which can then be authenticated with the public key. Make sure you keep the private key safe. As long as nobody gets access to the generated private key, all the peers connecting to the secure host can verify that the host is actually secure.
Creating a secure host
To create a secure host, simply set the private key in the host config.
// Create config
HostConfig config = new HostConfig() {
PrivateKey = /* ... generated private key ... */,
};
// Create host
Host host = new Host(config, listener);
// ... start accepting connections ...
Verifying a secure host
To verify that you're connecting to a secure host, simply set the public key in the peer config. Make sure you do not include the private key here as the private key should be kept a secret. Private keys are only neccesary for secure hosts, not for clients.
// Create host config
HostConfig hostConfig = new HostConfig() {
PrivateKey = null, // No private key here
};
// Create host
Host host = new Host(hostConfig, listener);
// Create peer config
PeerConfig peerConfig = new PeerConfig() {
RemotePublicKey = /* ... public key of the secure host ... */,
};
// Connect
Peer peer = host.Connect(address, peerConfig, new PeerEvents());
The connection will fail if the remote host was not authenticated properly.