When I read about this the first time, I was really impressed how easy and secure it is. But what is this all about? Sometimes you may want to share a secret among others in a special way. Imagine you have five administrators in your company. They will need to have access to most of your hardware and applications somehow. So you will have to give them e.g. root access on your Unix servers so they can maintain them. Let’s assume you have a special server, where your LDAP is running or your company’s private keys are stored and you don’t like any of your administrator to have „unlimited“ access to it. What do you do? Even this server has to be maintained and accessed by someone, right? So why don’t you share the root password (secret)? You could give all of your administrators a unique share and define, that a minimum of two shares are needed to access the server. This would be an easy way to implement a four-eyes principle. But how?
There is a neat way on doing this. It is called Shamir’s Shared Secret. The famous Adi Shamir, who also provided his name to the Rivest-Shamir-Adleman cryptosystem (RSA), also created this cryptographic algorithm. It allows you to divide a secret into parts (called shares). Each part can be handed out to a person or organization. The nice thing about this algorithm is, that some or all parts are needed to reconstruct the secret (called threshold). In order to understand the algorithm you would only need to know basic algebra only. There is a nice blog post from DataGenetics explaining this algorithm in a nice way.
We’ve implemented Shamir’s Shared Secret in PHP. It is on GitHub under MIT license.
The installation assumes, that you have composer installed already. After that you only need three little steps:
# git clone https://github.com/teqneers/shamir.git # cd shamir/ # PATH_TO/composer.phar install
How to use it
The easiest way to en-/decrypt is by using the console. The script
bin/shamir.php will provide you with some help.
So let’s assume, we want to create shares for all our administrators. We need to encrypt the password „4eyesonly“, which is our root password for the special server.
# bin/shamir.php shamir:share The secret to share: 4eyesonly Number of shared secrets to create : 5 Number of shared secrets required : 2 102011l2s5j1f0g4w0z264. 102021z302k0j3;1b4,1;19 10203243h585a1u3m371r3e 102042i3y294e58011m1f5j 102052w464*3i2%2c5o131,
Each of these shares needs to be handed out to your administrators. A single share won’t recover the secret. A minimum of two is needed to do so.
Any two of the shares can recover the secret again. We can use the same script just with a different argument.
# bin/shamir.php shamir:recover Shared secret [empty to stop]: 10203243h585a1u3m371r3e Shared secret [empty to stop]: 102011l2s5j1f0g4w0z264. Shared secret [empty to stop]: 4eyesonly
Of course this procedure wouldn’t be very helpful for our example, because the administrators would know the secret in that moment. So you might want to develop your own solution and implement the algorithm into your authentication module.
Here is the programmatic way of en-/decrypting your secret.
<?php require_once __DIR__ . '/../vendor/autoload.php'; use TQShamirSecret; // create 5 shares with a threshold of 2, // so you will need a minimum of 2 shares // to recover the secret. $shares = Secret::share('4eyesonly ', 5, 2); // output your shares var_dump($shares); // we can use different keys to recover the data, // but we need at least 2 of them both dump will // recover the secret and can be used to // authenticate the 2 admins var_dump(Secret::recover(array_slice($shares, 0, 2))); var_dump(Secret::recover(array_slice($shares, 1, 2)));
Try it out and let us know how you like it.