If usage of Certificate Authority (CA) and Certificate Signing Request (CSR) is too sophisticated for your task, you can use self-signed certificates.
Let say, there is 1 server and 2 (or more) clients.
Execute at client1:
openssl req -x509 -newkey rsa:4096 -nodes -keyout client.key -out client.crt -days 3650 -subj '/CN=client1' # generate client1 cert and key
sudo bash -c 'echo "192.168.1.101 my.server" >> /etc/hosts' # create domain for server - if necessary only
scp client.crt [email protected]:/path/to/certs/client1.crt # copy public cert client1 to server machine
Execute at client2:
openssl req -x509 -newkey rsa:4096 -nodes -keyout client.key -out client.crt -days 3650 -subj '/CN=client2' # generate client2 cert and key
sudo bash -c 'echo "192.168.1.101 my.server" >> /etc/hosts' # create domain for server- if necessary only
scp client.crt [email protected]:/path/to/certs/client2.crt # copy public cert client2 to server machine
Execute at server:
openssl req -x509 -newkey rsa:4096 -nodes -keyout server.key -out server.crt -days 3650 -subj '/CN=my.server' # generate server cert and key
scp server.crt client1-user@client1-addr:/path/to/certs # copy public cert server to client1 machine
scp server.crt client2-user@client2-addr:/path/to/certs # copy public cert server to client2 machine
cat client1.crt client2.crt > client.crt # combine client certs into the single file
Server code:
var clientCert = File.ReadAllText(Path.Combine(certPath, "client.crt"));
var serverCert = File.ReadAllText(Path.Combine(certPath, "server.crt"));
var serverKey = File.ReadAllText(Path.Combine(certPath, "server.key"));
var keyPair = new KeyCertificatePair(serverCert, serverKey);
var credentials = new SslServerCredentials(new List<KeyCertificatePair> { keyPair }, clientCert, true);
var server = new Server
{
Services = { MyService.BindService(new MyAdminService()) },
Ports = { new ServerPort("0.0.0.0", 54321, credentials) }
};
Client code:
var serverCert = File.ReadAllText(Path.Combine(_certPath, "server.crt"));
var clientCert = File.ReadAllText(Path.Combine(_certPath, "client.crt"));
var clientKey = File.ReadAllText(Path.Combine(_certPath, "client.key"));
var credentials = new SslCredentials(serverCert, new KeyCertificatePair(clientCert, clientKey));
var channel = new Channel("my.server:54321", credentials);
var client = new MyService.MyServiceClient(channel);
IMPORTANT!
To use TLS certificates, use a domain name when generate server certificate.
Client certificates can use any unique string.
Domain name should contain at least 1 dot (.), e.g. my.server
or my.server.customzone
If use top-level domain like my-server
, it causes a long waiting to resolve it (for me it always about 76 seconds).
Pros:
- no need to generate CSR, pass it to machine with CA, sign it there and copy back to originating machine
Cons:
- adding new client requires adding certificate to server