NAME
Secret::Simple - Secure secrets in configurations and code
VERSION
This document describes Secret::Simple version 0.11
SYNOPSIS
# OOP style
my $ss = Secret::Simple->new();
my $ciphertext = $ss->encrypt($plaintext);
my $plaintext = $ss->decrypt($ciphertext);
# procedural style
my $ciphertext = ssencrypt($plaintext);
my $plaintext = ssdecrypt($ciphertext);
DESCRIPTION
This module implements a straightforward interface for encrypting and decrypting secret information such as user IDs and passwords (e.g. database connection or remote account credentials). Secret::Simple
can also be used on a limited basis to protect arbitrary data. By default the ciphertext returned is Base 64 encoded so as to be easily embedded within configurations or scripts. A command-line utility called sstool
is included to facilitate easy manipulation of cipher and plaintext snippets.
The encryption mechanism utilizes the strong AES algorithm, so any weaknesses in Secret::Simple
predominantly lie in how keys are protected. A balance must be struck between key accessibility, key protection, and overall complexity. The calling code can supply a key, series of keys, key files, or a combination. If no key information is explicitly passed, the module will attempt to use the OS user's private SSH DSA key file by default if it exists.
The major goal of this module is to be as secure as possible while being simple and convenient enough to encourage its use. Psychology does factor in: simple is a very important consideration. If the security methods are too onerous or complicated to use, many sysadmins or developers may simply use plaintext (no protection other that OS file permissions) or simple ciphers like rot13. The security of the Secret::Simple
method is not perfect, but it does represent a significant improvement over commonly-used nonsecure methods of embedding credentials and other secrets in Perl configurations and scripts. If used appropriately, Secret::Simple
can greatly improve application and configuration security. Even so, care must always be taken to protect files and file permissions.
METHODS
new()
my $ss = Secret::Simple->new(); # default to user's private SSH DSA key
my $ss = Secret::Simple->new('my secret key');
my $ss = Secret::Simple->new( %options );
my $ss = Secret::Simple->new( \%options );
The constructor returns a Secret::Simple object. Valid options are:
- -key
-
The value of this parameter can be a scalar or array reference. Multiple elements will simply be concatenated together. This option accepts raw key data by default, but can also accept file-based key data according to the following parameter value syntax:
'secret key phrase' - string is the literal key (default) '{sskeyfile}/path/key.raw' - read raw key from file '{sskeyfile}' - read raw key from default file
Specifying
{sskeyfile}
by itself will designate the same behavior as the default of passing no key information: the constructor will attempt to use the literal contents of the current user's~/.ssh/id_dsa
file as a key. - -keyfilesize
-
Specifies the maximum number of bytes to read from a single key file. The default value of 0 is unlimited, but performance problems may quickly arise if large files (e.g. MP3) are utilized as keys.
decrypt()
Returns the literal plaintext of the supplied encrypted and Base 64 encoded value.
Example:
my $DBCRED = 'zzpjnDlUqz3+KCke5Rr4dA=='; # plaintext is jblow^secret
my $ss = Secret::Simple->new();
my ($user, $pass) = split /\^/, $ss->decrypt($DBCRED);
decryptraw()
Performs identically to the decrypt()
method except that the value passed is assumed to be raw ciphertext (no Base 64 encoding).
encrypt()
Returns the Base 64 encoded ciphertext of the supplied literal plaintext.
Example:
my $ss = Secret::Simple->new();
my $ciphertext = $ss->encrypt('jblow^secret');
# ciphertext will resemble: zzpjnDlUqz3+KCke5Rr4dA==
encryptraw()
Performs identically to the encrypt()
method except the resulting ciphertext is returned without the Base 64 encoding.
key()
This method can be invoked without an argument to obtain the current key specification value(s). Note that this is not necessarily the same as the information returned by the keydata()
method. Invoking with an argument will establish new settings. See the description of the new()
method's -key
option for more details.
keydata()
Returns the combined raw key data. The returned data represents the aggregate raw key if multiple keys and key files were specified.
keyfilesize()
The maximum number of bytes to read from a single key file. This method can be invoked without an argument to obtain the current limit setting (default 0 is unlimited). Invoking with an argument will establish the new setting.
EXPORTED FUNCTIONS
Secret::Simple
exports some functions you may use to avoid the OOP interface if you wish.
ssdecrypt($b64ciphertext, [key1], [key2], ...)
This function requires a minimum of one argument: the Base 64 encoded ciphertext to be decrypted. Any number of optional additional arguments may be specified as key values that follow the same rules as the new()
constructor's -key
option.
Examples:
my $DBCRED = 'zzpjnDlUqz3+KCke5Rr4dA=='; # plaintext is jblow^secret
# 1. simple
my ($user, $pass) = split /\^/, ssdecrypt($DBCRED);
# 2. id_rsa instead of id_dsa
my ($user, $pass) = split /\^/, ssdecrypt($DBCRED,
'{sskeyfile}~/.ssh/id_rsa');
# 3. more complex example
my ($user, $pass) = split /\^/, ssdecrypt($DBCRED,
'{sskeyfile}', '{sskeyfile}/path/otherkey');
ssdecryptraw($ciphertext, [key1], [key2], ...)
Performs identically to the ssdecrypt()
function except that the value passed must be raw ciphertext without Base 64 encoding.
ssencrypt($plaintext, [key1], [key2]...)
This function requires a minimum of one argument: the plaintext to be encrypted. Any number of optional additional arguments may be specified as key values that follow the same rules as the new()
constructor's -key
option.
Examples:
# use default ~/.ssh/id_dsa key
my $ciphertext = ssencrypt('jblow^secret');
# use explicit passphrase
my $ciphertext = ssencrypt('jblow^secret', 'secret key');
# use combination of two key files
my $ciphertext = ssencrypt('jblow^secret',
'{sskeyfile}/path1/key1', '{sskeyfile}/path2/key2');
ssencryptraw($plaintext, [key1], [key2], ...)
Performs identically to the ssencrypt()
function except the resulting ciphertext is returned without the Base 64 encoding.
DEPENDENCIES
This module requires the following other modules:
Carp
Crypt::CBC
Crypt::Rijndael_PP
Exporter
MIME::Base64
AUTHOR
Adam G. Foust, <nospam-agf@cpan.org>
COPYRIGHT AND LICENSE
Copyright (c) 2006, Adam G. Foust. All rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.