Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

The problem statement is: To supply clients on a network with individual Private & Public keys generated on a Server over the wire(over a HTTPS connection after they are registered). The clients are iOS & Android apps, and the server is generating keys using the OpenSSL library on PHP. The clients will then proceed to store the keys to sign further communication.
Additional Note:
[1] The apps must also have Server's public key to verify signatures.
[2] No encryption will be effected with the keys. Just signing.

What is the best way to supply the keys to the apps so that they can have it with them in formats they support natively? So far I have read about plenty of formats and file structures to supply keys, but anybody experienced with this situation and could guide as to which format is the most hassle-free to use?

share|improve this question
add comment

2 Answers

Not entirely sure what you're asking; if your apps natively support a specific format, use that. Is there a specific app you'd like to ask about?

If you just want a simple format for apps you're writing, the OpenSSH format is nice and simple (and widely used / supported). Also X.509 certificates are a little more complicated, but also widely supported, though that might be a bit beyond the scope of what you're trying to do (X.509 is a full spec for PKI [Public Key Infrastructure] and PMI [Privilege Management Infrastructure]).

OpenPGP also has free implementations (gnupg), and has good library support / a nice key format (when using ascii armoring).

[OT]: On a semi-offtopic note, generating the private key server-side and then giving it to the client is almost always a bad idea that defeats the purpose of public/private key crypto. Instead you should pre-seed the clients with the servers public key, generate a private key on the client, use the servers public key to verify the connection (if you're already using TLS you've done this part) and then send the server the client's public key. Also, if you're already using TLS I'm not sure why you'd need another layer, then again, I don't know what use case you had in mind.

Examples

To get an example of each key on a Unix/Linux system:

OpenSSH: ssh-keygen -t rsa -b 2048 -f filename

GnuPg: gpg --keyserver pgp.mit.edu --recv-key 0xEC2C9934 && gpg --armor --export 0xEC2C9934 (will download and display my public key)

X.509: openssl genrsa -sha512 -out keyfile.key 2048 will spit out a private key. You can then generate a certificate signing request using openssl req -new -key keyfile.key -out keyfile.csr and finally a certificate: openssl x509 -req -days 1 -in keyfile.csr -signkey keyfile.key -out keyfile.crt

Final Thoughts

After reading the comments, it seems you're looking for more of a full solution. If I understand what you want, I think the ideal solution would be to use X.509 certificates. You could either create your own CA (Certificate Authority) or purchase a certificate from a trusted third party online (I like RapidSSL). You can then have your apps verify communications from the server, and use ECDH (Eliptic Curve Diffie–Hellman) to negotiate a shared key and facilitate secure communications (You said you wanted small footprint, so I figure ECDH will be faster than normal DH). AES256 for encryption and SHA2 for message digest verification should give you a secure, well supported, and reasonably low overhead connection. Basically just use TLS and make sure you choose good options for the encryption type, key exchange mechanism, and message digest function.

share|improve this answer
    
Thanks for the response. I would build apps for iOS/Android which would connect to my Web Server over HTTPS. Additionally, the apps would also connect to other Web Servers which would provide supplementary services. It is for this part that I am trying to implement a PKI, so that the apps can identify themselves to the supplementary Web Servers and vice versa. I also agree that generating Private key off-site is against the principle, but then how could I make sure that all public keys across the network are recognised as valid by my Web Server? –  kumar Jun 12 '12 at 21:03
    
Ah, for this use case I think the OpenPGP PKI would probably be best. You could either maintain a private keyserver (lookup SKS) or just upload each key and have your server distribute it to the subnodes as required. Unless I'm misunderstanding something, or you want to ensure that ONLY your apps can communicate with the server, in which case I think you're right. Have you considered using a cryptosystem with perfect forward secrecy (where the key is renegotiated per session)? –  Sam Whited Jun 12 '12 at 21:18
    
Now that I have seen the PGP scheme, and if you have understood my use case, should I just use a keyserver(holding all validated public keys active on the network)? And then how different is this from PKI? I am more confused now. –  kumar Jun 13 '12 at 0:26
    
Sorry about that. PGP's keyservers are part of its Public Key Infrastructure (PKI) which encompasses the entire cryptosystem, distribution, etc. In my opinion this isn't a very good way to solve your problem though (I was just suggesting it to cover all the bases, since I don't know the specifics of what you're trying to do). The best way would probably be to just use SSL/TLS with AES encryption, EKDH key exchange, and SHA512 message digest verification. –  Sam Whited Jun 13 '12 at 3:57
    
Its ok @SamWhited, I now have some clarity on which way to proceed. I read up some good articles about PGP vs PKI, PKI and PGP in itself, and that helped. Thanks for chipping in. –  kumar Jun 13 '12 at 4:03
show 1 more comment

I have done something similar to this setup and would recommend going with a more standard X509 PKI setup over the OpenPGP. There is a little more to understand and well worth scripting if you use it often however it will fit your model.

Essentially you want to create your own Certificate Authority (CA). When new applications come online they create a private/public key, wrap the public key in a certificate that provides identification of who owns that key and sends it to the CA to be signed in a Certificate Signing Request (CSR). This is the standard way of accepting new public keys without generating private keys on the server. It is obviously an attack point, but with the same risks as sending keys to your apps.

A major advantage of X509 is the tie in to your webserver and HTTPS. Most(/all) major webservers are capable of accepting a client certificate and ensuring that the certificate has been signed by the CA before it hits your server application and passes the public key and certificate name (CN) to your server for client specific information.

There are plenty of places on the web to help setting up X509 CAs and how to sign with them and handle client certificates and most are daunting but i think long run this is better suited than PGP.

Edit to better address the specifics of the question:

Identifying the server means the application must know and trust the CA which should be easily known in advance. Connecting over HTTPS can verify that the server presents as the correct host example.com and the certificate is signed with your CA.

Using this method you can simply store the private and public key in a PEM file which is just text or a variety of other formats depending on what works best for your app. You then provide it in your call to the webserver as a client certificate, this is obviously dependant on your http library (and i don't know about android's or ios') but i'm sure they have it. Then you simply make requests over POST or whatever means you wish.

share|improve this answer
    
First off, welcome to security.se. Altho am no old timer, still. Moving on, between SamWhited's and your answer, I guess I'm getting what is being told here. I may not use the entire certificate format, but what can happen on first contact between 2 entities is, they exchange their public keys, and the signatures signed by the CAs private key in 2 variables in a GET/POST request. Thanks for your response again. EDIT: I'm writing this after your edit, to address it. I also require the Web Services to verify the apps, so the apps also need a pair of keys with them. –  kumar Jun 13 '12 at 2:55
    
For my purposes I always suggest and try to use something that is accepted, and verified to be correct. By using the full format you are sure the security is done correctly because it has been created and verified by smarter people than myself. I suggest you do not try to come up with your own solution for exchanging and signing keys. The web services can indeed verify the apps using this method, have a look into client certificates in your server language for more details. Unfortunately IMO the openssl library/app sucks (from a usability view), but it will suit your purposes. –  jumentous Jun 13 '12 at 3:22
    
I am indeed trying to keep myself from rolling anything of my own, but here's the thing if I go with certificates. The connections between the apps and other services(services other than CA) will not be SSL, so I'm not sure how will these certificates work there. Additionally, I want one request-response to do as much of the work as possible as low-latency is a design goal, and so would a certificate exchange take up one such full request-response? –  kumar Jun 13 '12 at 3:32
    
The client certificate exchange happens within the HTTPS handshake. So every connection will be secured and the exchange will happen on initial https request, ie within the data exchange connection. –  jumentous Jun 13 '12 at 4:04
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.