The keychain provides a way to securely store sensitive information such as access credentials or any other data.
The system relies on three files:
The passphrase file is generated by using the private key to encrypt the passphrase. This is so that the passphrase file can be decrypted by the public key without requiring the knowledge of the passphrase for the private key. This means it can be deployed onto a server without requiring manual intervention or a passphrased stored plain text on disk. Because of this the public key should not be stored in a repository and should be stored on servers in a protected location.
The keychain file is the actual valuable contents. It is encrypted using the passphrase stored in the passphrase file (which itself is decrypted using the public key).
This provides a balance between not storing credentials plain text but also making the system reasonably independent.
A good example of where the keychain is useful is where some code needs to establish a connection with another server or service using some access credentials (usually a username and password, but any number of authentication credentials could be used); using clear text credentials in the code, which is probably stored on a relatively public code repository, can be avoided by storing the credentials in an encrypted data file that the keychain can read.
You can store the private key in a code repository but you MUST NOT commit the public key. Doing so will compromise the security of the keychain (you will need to regenerate the private key if you accidentally do commit it).
JKeychain class extends
JRegistry. There are no changes to the
constructor's argument list so optional initialisation with data can be
done in the normal way.
// Create a keychain. $keychain1 = new JKeychain; $keychain2 = new JKeychain(array('username' => 'foo', 'password' => 'bar'));
JKeychain object operates in the same way as a
JRegistry object. What
JKeychain provides is a way to load data from, and store data to an
encrypted data source.
When using this class, the private and public keys must already exist on the server. The third required element is the passphrase file and the following example shows how to create it.
// Create a keychain object. $keychain = new JKeychain; // The passphrase/passowrd should not be stored in any code repository. $passPhrase = 'the Pass Phrase'; $privateKeyPwd = 'the Private Key Password'; // The paths to keychain files could come from the application configuration. $passPhrasePath = '/etc/project/config/keychain.passphrase'; $privateKeyPath = '/etc/project/config/keychain.key'; $keychain->createPassphraseFile($passPhrase, $passPhrasePath, $privateKeyPath, $privateKeyPwd);
The passphrase file will generally be created using the Keychain Management Utility (see next section) on the command line so that neither the passphrase, nor the private key password are stored in clear text in any application code.
Likewise, initial data is probably already created in a keychain data
file (again, using the Keychain Management Utility and the
command). The following example shows how to load the keychain data:
// Create a keychain object. $keychain = new JKeychain; $keychainFile = '/etc/project/config/keychain.dat'; $passPhrasePath = '/etc/project/config/keychain.passphrase'; $publicKeyPath = '/etc/project/config/keychain.pem'; $keychain->loadKeychain($keychainFile, $passPhrasePath, $publicKeyPath); $secureUsername = $keychain->get('secure.username'); $securePassword = $keychain->get('secure.password'); $conn = connect_to_server($secureUsername, $securePassword);
The keychain object can manipulate data as if it was a normal
object. However, an additional
deleteValue method is provided to strip
out registry data if required.
saveKeychain method can be used to save data back to the
The keychain management utility (
/bin/keychain.php) allows you to
manage keychain resources and data from the command line.
$ keychain.php [--keychain=/path/to/keychain] [--passphrase=/path/to/passphrase.dat] [--public-key=/path/to/public.pem] [command] [<args>]
--keychain=/path/to/keychain- Path to a keychain file to manipulate.
--passphrase=/path/to/passphrase.dat- Path to a passphrase file containing the encryption/decryption key.
--public-key=/path/to/public.pem- Path to a public key file to decrypt the passphrase file.
Lists all entries in the keychain. Optionally pass --print-values to print the values as well.
create entry_name entry_value
Creates a new entry in the keychain called "entry_name" with the plaintext value "entry_value". NOTE: This is an alias for change.
change entry_name entry_value
Updates the keychain entry called "entry_name" with the value "entry_value".
Removes an entry called "entry_name" from the keychain.
Outputs the plaintext value of "entry_name" from the keychain.
Creates a new passphrase file and prompts for a new passphrase.
On a command line with openssl installed (any Mac OS X or Linux box is suitable):
$ openssl genrsa -des3 -out private.key 1024
This command will generate a new private key in the file "private.key". This can be then used to create a new public key file:
$ openssl rsa -in private.key -pubout -out publickey.pem
This will use the private key we just created in private.key to output a new public key into the file publickey.pem.
If you need to generate keys with certificates (exact details will vary from system to system), on a command line with openssl installed:
$ openssl req -x509 -days 3650 -newkey rsa:1024 -keyout private.key -out publickey.pem
This will create a new private key in the file private.key and a new public key in the file publickey.pem. You will be asked for a passphrase to secure the private key. and then prompted for information to be incorporated into the certificate request:
Country Name (2 letter code) [AU]: US State or Province Name (full name) [Some-State]: New York Locality Name (eg, city) : New York Organization Name (eg, company) [Internet Widgits Pty Ltd]: Open Source Matters, Inc. Organizational Unit Name (eg, section) : Joomla! Platform Common Name (eg, YOUR name) : Joomla Credentials Email Address : firstname.lastname@example.org
Once this is done there will be a
that you can use for managing the passphrase file.
This step requires that you have already generated a private key (and
keychain.php file is executable and in your lookup path).
The following command will initialise a new passphrase file:
$ keychain.php init --passphrase=/path/to/passphrase.file --private-key=/path/to/private.key
This will prompt for two things:
It will create a new file at
/path/to/passphrase.file replacing any
file that might be there already.
This step requires that you have already generated the private key and the passphrase file. The following command will create or update an entry in the keychain:
$ keychain.php create --passphrase=/path/to/passphrase.file --public-key=/path/to/publickey.pem --keychain=/path/to/keychain.dat name value
An existing keychain file will attempt to be loaded and then key name will be set to value.
If you know the passphrase for the private key but have lost the public key you can regenerate the public key:
$ openssl rsa -in private.key -pubout -out publickey.pem
This will use the private key in the file
private.key and output a new
public key to
publickey.pem. If the private key has a passphrase on
it, you will be prompted to enter the passphrase.