Why does GPGME / GnuPG use pinentry for password input? - c++

GPGME uses a passphrase_cb method to fetch the password from the user for operations, which require access to private keys. This callback can only be overwritten for symmetric encryption, in all other cases the default pinentry is used.
All this effort seems to be pretty uncomfortable, especially because GPGME is an API which shall be used for programming C/C++/... applications. It might be easier (for a programmer who would like to use GPGME) in some cases if the passphrase could be passed to encrypt/sign functions directly. I also saw that other implementations of OpenPGP (to be more precise NetPGP) use a callback.
So I wonder if there is any security specific reason to do so?

GnuPG starting with 2.1 removed the most critical private key functionality into the gpg-agent, to reduce the attack surface on the most intimate secrets -- the private keys.
Such a callback would not only expose the passphrase to the application you're writing (which probably means an even larger attack surface than GnuPG would be), but also GnuPG gets aware of the passphrase.
If you really need to control entry of the passphrase from your application, you have several choices.
Implementing Pinentry
The information flow would then be: your application calls GnuPG through GPGME, GnuPG requests some private key operation from gpg-agent, which again asks your application for the passphrase. Be aware this will only work if you also started the gpg-agent with appropriate pinentry configuration (you might have to start another instance, separate from the one already running on your system).
gpg-preset-passphrase
The most important use case of passing the passphrase directly is in headless daemons, where no humans waits for entering the passphrase. GnuPG also brings a small utility gpg-preset-passphrase (on Debian and derivatives, it is installed as /usr/lib/gnupg2/gpg-preset-passphrase), which also can be used to precache the passphrase (so it is not queried for a configurable time).
Pinentry Loopback
With GnuPG 2.1, another option was added: in gpg-agent, you can allow pinentry loopback with the allow-loopback-pinentry option. An additional parameter pinentry-mode set to loopback in GnuPG/GPGME should allow you to handle passphrase interaction using passphrase_cb again.
But: consider this exposes the passphrase not both your application and GnuPG, and might prove to be a (possibly minor but existing and maybe unnecessary) security risk. Also, GnuPG 2.1 is not yet widely spread, which might be a problem if you do not control the environment.

Related

Simple payload encryption in C++

I have different applications that must communicate among themselves. They can use both UDP and TCP and there can be more than one link between two specific applications. My idea is to encrypt the communications using AES, storing the password somewhere in the computer (encrypted). The password that will be used is of course the same for all the applications and will be changed once in a while. The language I'm using is C++ and I was thinking to use libcrypto++ but I'm open to suggestions.
I know about OpenSSL, TLS etc but what I'd like to do is a really simple encryption of the payload of my custom application protocols. Is there any particular problem that I should pay attention to when implementing this, like message boundaries etc?
Another question is: is it possible to only get the shared key from a central server via SSL or other, and then use this for the above encryption? this will be done from the application at startup and the password could be stored in RAM.

Synchronizing GnuPG private keys between multiple servers for horizontal scaling

I am using CentOS 7 and GnuPG 2.0 for one of my applications which is using encryption and decryption.
Now I am trying to scale my application horizontally, on two server named as server A and server B.
Let's say the application creates a private/public key pair on server A, how can I share the same set in server B or vice versa, so that application can access same set of keys from either servers?
Given you do not describe any method which does not store the locally, you're probably using a normal GnuPG home directory with the private key stored in the keychain. Just export this key (gpg --export-secret-keys <key-id>) and then import it (gpg --import) using the same mechanics for distributing other credentials (database, ...).
GnuPG keys do not change "on their own", usually are long-lasting and creation is often a manual process; so you don't need to actively monitor and synchronize them. Just roll out the new copy in the rare case they actually change. Again -- compare the process to database passwords or other secrets.
If keys are actually regenerated regularly, you will have to run the export-import-process whenever creating new keys (and be sure to consider timing issues with the synchronization process not being finished yet, but access is already spread among the servers).
A (much more complex and error-prone, if you don't know the technology in detail) alternative is to use a gpg-agent socket shared over the network, for example by using SSH tunnels or similar solutions. This allows all connected servers to use the private key, without having it stored locally. This might especially prove important if you cannot (may not) store the private key locally. Using gpg-agent socket sharing, the private key is never leaving the server running gpg-agent, which performs all private key operation (the major parts for handling encryption is usually formed by the symmetric encryption of the actual data, but make sure you don't run into scaling issues!).

Client / Server Cryptography for passwords

I am building a client/server application in C++ and need each client to provide a password. Obviously I want this to be secure during transport so I have been looking into a way of encrypting the password; so that only the server application can decrypt it again.
The problem I am having is not necessarily getting the functions to work, but rather understanding what it is I need to do in order to relate that into code. I am trying to understand and have read MSDN (feels like it) but still I am only learning so really need some clear and accurate guidance on my implementation.
Does this sound right?
I aquire a context to the CSP on both server and client.
I generate a key on the server, or load one (whatever).
and then I
export a public key from the server and send it to the client, the client imports the key and then encrypts the password and returns it so that only the server can decrypt it again.
(Fails when I try).
OR, do I then
export a session key, or an exchange key pair ( single public) which is encrypted with the exchange key pair?
Oh I am so lost, I cannot even explain clearly.
Please help me to understand this...
It really depends on what sort of authentication solution you want to be based one. The options are varied.
You could, for example, rely on the underlying OS authentication. You wouldn't need to manage passwords at all. But this requires a somewhat tighter integration with the domain in which your application is running.
Another option is to use HTTPS and simple authentication. It basically uses SSL to encrypt communication and then sends a username/password pair. Pretty simple, and supported by all web servers. You could probably find C++ code quite easily that takes care of this for you (search StackOverflow for such a question) if you don't want to rely on an existing web server like IIS being installed.
If you do not need the encrypted Communication for other things like data transfer, you can use Challenge-Response for password verification. The Password does not need to be transferred over the network and there is no risk of a replay attack in wich a third party just resends some packets. On the downside, a man in the middle (MITM) attack is possible.
If you need protection from MITM or need an encrypted channel for other communication, you should use TLS with certificates or Public-Key-Encryption with two keypairs.
Do not do anything.
This is very important. Do not implement this yourself.
Repeat do not do anything you will get it wrong.
You should use what is already available. Simply open a connection to an SSL socket and the content of the stream will be automatically encrypted and de-crypted at the other end.
Your application should simply take a username/password tupple and validate if they are correct. Do not attempt to implement the cryptographic part.

Algorithm to generate security token for MMO Login Service

I'm building a Login Service for an open source MMO game. I do not know much on the side of security/encryption and I am looking for a solution that will provide good protection against hackers and must not be too costly to generate.
Our old system used a very simple system of authentication by storing the password as SHA1 in the database. For our new service we want to authenticate this through an auth token that is generate when the user logs in for the first time and is valid throughout the session. Would a simple randomly generated string suffice for this or should I be looking at something more complicated to keep it secure?
Don't reinvent the wheel. The biggest problem with modern cryptography is when people want to roll their own, use SSL/TLS or HTTPS. This can be done safely without buying a certificate if you hard-code a self-singed certificate. Although each server should have its own certificate, or you run this risk Of MITM.
What you are looking for is a Session Handler, and ideally you would use the witty library. However this library may or may not be appropriate. In short a session handler uses a Cryptographic Nonce as a key, and this key is used to look up session state in a persistent data store. Each time a user authenticates he is given a new Cryptographic Nonce, and this value expires after a set amount of time of inactivity. For nonce generation I would use the openssl library, and 256 bytes in size should be plenty. A timeout depends on your application, but it should be no more than 1 day.
Rule 1: don't try to build your own single sign on.
Rule 2: If tempted, refer to Rule 1.
There are lots of freely available systems. Consider using OpenID. It's simple, pretty strong, and free.
PS. Have a look at the Wiki article.
Well there are so many vectors of attack in a system. These sorts of problems are quite complicated to solve properly. First step would definately be to make sure you're not re-inventing the wheel, it will save you time and probably prevent a host of mistakes.
I did build a system recently. In my case I didn't need secrecy I just needed authenticity. I built my system on top of openssl's crypto library. I used predominantly the DSA algorthim. Communication was autheticated with signatures attached to all comms. It's not particularly efficient to do it that way but for my purposes communication was irregular and as such it was fine. The relevant key was distributed with the software for generating DSA signed comms.

Public key or Diffie-Hellman Key Exchange Algorithm

Consider and client server scenario and you got two options:
You can include Server's Public Key
in Client and perform the exchange.
You can use Diffie Hellman
KeyExchange Algorithm to handshake
and then exchange the key.
Which one is more secure way?
also if public key will come from store say from Client CA store? would it be more secure instead of binding it in Client app?
The deployment will be done via an installer, verifying the version on each run.
With (only) DH key exchange, the client has no way to know that it is really the server he is talking to.
So the conversation would be secure from eavesdroppers, but someone could pretend to be the server and compromise the client.
Don't.
If you need to solve this kind of problem in production code, have an expert do it. There are so many subtle pitfalls in cryptography that chances are you will come a cropper.
An embedded key can be replaced. Generally speaking, if the client's machine is not secured by non-software means, you cannot prevent hacking of your client by a sufficiently motivated attacker. Even a TPM is no panacea. The question becomes one of trade-off: attackers' man-hours vs. utility (profit, fame &c) gained. The only really secure way to license a program which does computations is to perform all licensable computations on a server you physically control; https or SSL can be made sufficiently secure by choosing appropriate key lengths, hashing schemes, ciphers &c (a subject of which I know little).
The principle here is actually rather simple: you need to engineer a situation in which it will be in your clients' best interests to protect their passwords/license keys/data/whatever. E.g. if you have a computation server and charge your clients for server time, client keys are proxies to owners' bank accounts.
With the public key scenario the client must be generating the key, there is no way you can have any confidence this key is securely generated (someone could get access to the system and change the key generator to always use the same value, increment the previous value by one, whatever, said attacker can then eves drop on your communications for ever more). Public key crypto was not designed for this purpose.
Diffie-Hellman would be better but as Tobias said if you roll your own you'll probably leave an attack.
Well private key algorithms usually offers better performances (by an order of magnitude or more as far as I can remember) then their public key counterpart. In that sense Diffie-Hellman would be more efficient then say RSA for a client-server architecture.
If you have far far more clients then servers, you could implement a public-key algorithm to reduce the exchanges between them.
Still, like many people said, you should consider asking/hiring an expert on the matter as there is many different types of attacks (most of them targeting only the implementation and not the algorithm per se). If you still want to proceed, I can only wish you best of luck and point you to this resources you should very carefully read.
Diffie-Hellman Key agreement method
As Tobias mentioned above it is better if you don't roll your own protocol. I would suggest to use an implementation of TLS, or at least model your protocol on TLS. TLS provides options for both Diffie-Hellman and Certificate based key exchange.
Take a look at: http://en.wikipedia.org/wiki/Secure_Sockets_Layer