I have a web application that needs to store server login information. I'm using a 2048bit PGP public key to encrypt inserted passwords (see the insertServerDef
) and a private key with a passphrase to decrypt the passwords (see getServerDef
).
As I understand things, the weakest link in this chain is the handling of the private key and passphrase. As you can see from my code below, I'm just using file_get_contents
to retrieve the key and passphrase from files located in the current web directory--not good.
My question is: what is a good method for securely retrieving the private key and passphrase for use in decrypting login info? Maybe I should store/retrieve the private key via an authenticated remote file server?
I've searched for best practices, but haven't been able to find much.
class DB {
protected $_config;
protected $_iUserId;
protected $_iServerId;
protected $_dbConn;
protected $_sPubKey;
protected $_sPrivKey;
public function __construct($iUserId, $iServerId) {
//bring the global config array into local scope
global $config;
$this->_config = $config;
$this->_iUserId = $iUserId;
$this->_iServerId = $iServerId;
$this->_sPubKey = file_get_contents("public_key");
$this->_sPrivKey = file_get_contents("private_key");
$this->_sPrivKeyPass = trim(file_get_contents("private_key_pass"));
}
//connect to the database
public function connect() {
try {
$this->_dbConn = new PDO("pgsql:host=".$this->_config['db_host']." dbname=".$this->_config['db_name'],$this->_config['db_username'],$this->_config['db_password']);
echo "PDO connection object created";
} catch(PDOException $e) {
echo $e->getMessage();
}
}
public function insertServerDef($sHost, $iPort, $sUser, $sPass) {
//testing
$iUserId = 1;
$oStmt = $this->_dbConn->prepare("INSERT INTO upze_server_def (server_id, host_address, ssh_port, username, pass, user_id) VALUES (DEFAULT, :host_address, :ssh_port, :username, pgp_pub_encrypt(:pass,dearmor(:pub_key)), :user_id)");
$oStmt->bindParam(':host_address',$sHost);
$oStmt->bindParam(':ssh_port',$iPort);
$oStmt->bindParam(':username',$sUser);
$oStmt->bindParam(':pass',$sPass);
$oStmt->bindParam(':pub_key',$this->_sPubKey);
$oStmt->bindParam(':user_id',$iUserId);
$oStmt->execute();
}
public function getServerDef($iServerId) {
$oStmt = $this->_dbConn->prepare(" SELECT server_id, pgp_pub_decrypt(pass,dearmor(:priv_key),:priv_key_pass) As decryptpass
FROM upze_server_def usd
WHERE usd.server_id = :server_id
");
$oStmt->bindParam(':server_id', $iServerId);
$oStmt->bindParam(':priv_key', $this->_sPrivKey);
$oStmt->bindParam(':priv_key_pass', $this->_sPrivKeyPass);
$oStmt->execute();
while($row = $oStmt->fetch()) {
echo "<pre>".print_r($row)."</pre>";
}
}
//close any existing db connection
public function close() {
$this->_dbConn = null;
}
//close any existing db connections on unload
public function __destruct() {
$this->_dbConn = null;
}
}
See Question&Answers more detail:os