4

I'm writing a client/server application that requires the server needs to be able to authenticate the client and also requires all comms to be encrypted.

The mechanism to provide this needs to be self contained within the server and client application and also to be fully automated (no human interaction required). SSL seems to be the best way to do this and is also something I am familiar with using.

For each client that needs the client software deploying to it, I planned to create (on the fly) an MSI installer with the application, the clients certificate (signed by the server) and private key and the servers public certificate (so the clients can authenticate the server - the server certificate could be self signed).

I can generate the key for the client and make a CSR, but don't seem to be able to find a way of actually signing the CSR and generating a certificate for the client thou. I have looked into the Win32 Crypto API, but haven't managed to find any examples of how to actually sign a CSR and get a client certificate.

I know how to do all of this from the command line with the openssl tool, but am not sure of how to do it from within an application.

Please note that making system calls out to the openssl tool and passing in the parameters I know to work is not an option as it's a huge security risk to rely on the openssl tool not being compromised in any way. Doing it this way wouldn't for fill the self contained requirement.

I am going about this the right way, or is there a better way to achieve the same thing - basically authentication of the clients connecting to the server and a way of the connecting client to authenticate the server they connect to, all encrypted.

I cannot make any assumptions about the server (or clients) having a static IP or hostname (DNS can be broken anyways), nor can I make any assumptions about any existing PKI infrastructure.

I am writing this primarily in C#.Net, but would consider writing a C++ extension to this if it gives me this functionality.

Finally this is my first post here, so if I've missed out something obvious or have been short on any details, please ask and I'll fill in the gaps :)

Thanks,

James

rb_
  • 613
  • 9
  • 24

2 Answers2

1

In C# you can use PKIBlackbox package of our SecureBlackbox product which provides all the functionality you are looking for in .NET. Maybe BouncyCastle library also includes this functionality.

Eugene Mayevski 'Callback
  • 45,135
  • 8
  • 71
  • 121
  • I had a look over BouncyCastles libs and I either couldn't find or they didn't have an example of what I was trying to do. PKIBlackbox on the other hand does, it ticks the boxes to do what I want to do, just gotta convince the boss it's worth buying! – rb_ Apr 06 '11 at 09:53
1

You need to rethink at least part of this. What you are doing is radically insecure. The client's private key needs to be generated at the client. Otherwise it isn't private, so it cannot possibly satisfy any of the tenets of PKI,. including the purpose for which you are issuing it. You lose uniqueness and you also lose non-repudiability. These are both fatal flaws.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • It's not crazy - if he generates the installer package with its embedded key, and as long as he controls access to that package then the only people who have extra access to the key are him - who he can implicitly trust - and superusers on the end system who could just read the key off anyway. The alternative would have to be to embed a signed token in the installer instead which the installed client can use to authenticate itself to a remote CA service after generating its own key, but that's a lot more hassle to set up for not a lot more gain. – Rup Apr 06 '11 at 08:49
  • EJP's points are valid to a point, I appreciate that the client should be the sole owner of their key, but in order to achieve that would involve some other mechanism on top of that to authenticate that client to the server, before the server could trust it to sign the clients CSR. If you can think of a better mechanism to achieve the same thing then let me know – rb_ Apr 06 '11 at 09:35
  • 1
    Basically how can the client generate and send a CSR to the server, when it has nothing on it that I am in control of yet and has no knowledge of the address of the server or it's cert. There will be a weak link in this chain somewhere, it's just where is the best place to put it - I reasoned the server as that should be secure anyway as it's where all the sensitive data will end up being processed and the clients managed. – rb_ Apr 06 '11 at 09:52
  • What I was suggesting: rather than including a key and signed cert in your installer, include a random token which you store in the server's database. The client can generate its own cert then send that cert plus the token to your CA. The CA checks the token is valid, signs the cert request then crosses the token off the list so that it can't be reused. So each installer is a one-use package, same as now. If it gets installed on the wrong PC then you can cancel access for the associated client cert and re-enable the token so that the installer can be re-used. But I think this is overkill. – Rup Apr 06 '11 at 10:10
  • Yeah this is an idea that's worth developing further that I hadn't thought of yet. Thanks for the help! Doing it this way makes the Installer package the weak bit, that (if I was a nefarious entity) would be the part I'd attack/steal, and there isn't really a way round that issue (except being careful about leaving installers lying about etc and applying a bit of common sense). – rb_ Apr 06 '11 at 10:32
  • @Rup As I said, he loses non-repudiation and uniqueness. Losing non-repudiation means that the client can repudiate a possibly multi-million dollar transaction simply because there isn't a legally effective signature. In practice the client must generate his own private key and communicate his certificate via a different channel, e.g. an offline one, typically involving a signed-for courier process. Trying to provide authentication material via the channel it is supposed to be authenticating is simply a contradiction in terms. You and the OP need to consider these points *most* carefully. – user207421 Apr 06 '11 at 12:28
  • OK, sure, but that's a major hassle for deployment and he hasn't actually said that non-repudiation is a requirement. We don't know exactly what he's doing. And if he cared about that sort of thing to that level I expect he'd be using hardware tokens for the encryption. We're both suggesting he provide the initial authentication in the installer, not over the network channel. – Rup Apr 06 '11 at 12:53
  • Yeah sorry for not being clear enough on that point, @EJP is entirely correct, this does fly in the face of proper security practice, but it's the age old battle between usability and security. I could require that the admins go round each client and generate a private key to be stored securely then generate a CSR, send that to the CA for signing and so on, but it would become unmanageable once it started scaling above 10 clients (and they might be geographically remote too). So using the installer as the initial way seems logical, but it does make it the weakest point in the chain... – rb_ Apr 06 '11 at 13:57
  • Breaking the security just to get the security implemented is *still* a contradiction in terms. If you don't want security, don't issue the certificates at all. If you issue them, do it right. There is no middle ground here. – user207421 Apr 07 '11 at 01:25