encrypt with keyfile, decrypt with password - php

I'm fairly sure this should be simple, but somehow I've come up short from Googling.
I am writing a php script on linux to encrypt files. I want anyone to be able to encrypt files using this script, but to require a password when decrypting the files.
I looked at GnuPG and openssl but they seem to require keyfiles when decrypting too, or password both when encrypting and decrypting - unless I missed something.
Basically I am working on a repository and the project's configuration files contain sensitive information that I don't want on the repo unencrypted, but I want to have a script all developers can use to easily encrypt sensitive files before they commit them to the repo.

This should be possible using both GnuPG and openssl.
You need to have an encrypted (i.e. - password protected) private key file and an unencrypted public key file. Anyone can encrypt using the public key, but decrypting requires providing the private key, which is password protected.
The only technicality is that you will need to distribute the key files to everyone.

After martinstoeckli asked the obvious question of "why can't you use a key to decrypt the files?", I thought I had thought of a hack, but apparently it's actually very widely used after googling around - my solution here involved using both a keypair and password.
Note: I generate the keypair in a temporary folder, else this keypair would exist on the keychain on the PC where they are generated, I do not want that, therefore I add --homedir /tmp/gnupg
I generate a password-less keypair with GPG - here's what I typed:
mkdir /tmp/gnupg
gpg --homedir /tmp/gnupg --full-gen-key
(1) RSA and RSA (default)
4096
0
y
mark
marklahn#domain.com
this key is used for protecting config files
o
Then export the private key, private key and ownertrust
gpg --homedir /tmp/gnupg --armor --export marklahn#domain.com > gpg_keyfile.pub
gpg --homedir /tmp/gnupg --armor --export-secret-keys marklahn#domain.com > gpg_keyfile.priv
gpg --homedir /tmp/gnupg --export-ownertrust > gpg_ownertrust.txt
rm -rf /tmp/gnupg
This is enough to encrypt and decrypt files without a password once the keys are imported to GPG's keychain.
Next up is password protecting the private key, so nobody can use it without having the password.
gpg -c --batch --passphrase password1234 gpg_keyfile.priv
BEWARE: GPG does NOT delete the original files, so when encrypting, remember to delete the original file if necessary
Then I can add all 3 files to the repository (gpg_keyfile.pub gpg_keyfile.priv.gpg gpg_ownertrust.txt - NOT gpg_keyfile.priv! ).
To encrypt a file on another machine:
1: import the public file and ownertrust
gpg --import gpg_keyfile.pub
gpg --import-ownertrust gpg_ownertrust.txt
2: encrypt the file with the public key
gpg -e -r marklahn#domain.com configfile.ini
configfile.ini.gpg should now exist, which can be commited to repo
Now when wanting to decrypt a file again, there's a couple of extra hoops to jump through to make sure the system doesn't save the private key.
1: First, the private key is password protected, so decrypt the private key:
gpg --batch --passphrase password1234 gpg_keyfile.priv.gpg
2: Then create a temporary gpg directory
mkdir /tmp/gnupg
3: import the private key to the temporary keychain
gpg --homedir /tmp/gnupg --import gpg_keyfile.priv
4: use the temporary keychain that now holds the private key to decrypt the file
gpg --homedir /tmp/gnupg configfile.ini.gpg
5: make sure to immediately remove the temporary keychain and private key
rm -rf /tmp/gnupg gpg_keyfile.priv
That works for me, now I can git clone a branch onto a new system, easily set up my application and decrypt my config files having just a password.

Related

gnupg decrypt command with php with passphrase

Im using Gnupg to decrypt a file:
gpg --decrypt -o file.xml file.gpg
You need a passphrase to unlock the secret key for
user: "TEST-COMPANY (DAM Key) <test#test.de>"
4096-bit RSA key, ID 257C2D21, created 2018-04-23
Enter passphrase:
Then I write this passphrase and then works.
And now I want to make it automatic using this command on PHP:
$command = 'gpg --decrypt -o file.xml file.gpg'
exec($command);
The problem came when system ask for phassphrase.
I tried this:
$command = 'gpg --decrypt -o file.xml file.gpg | [Passphrase]'
but doesn't work.
Any idea about this?
Thank you
Just adding the answer that the OP and #CD001 figured out in the comments, because it helped me immensely (thanks!), and seems like a common issue (secret key was generated with passphrase, and generating new keys isn't an option). I was pulling my hair out trying to decrypt with the GnuPG functions, before learning that as of GnuPG 2.1, it can't decrypt a file with passphrase-generated key (as noted in comment here). Configuring gpg-agent with a preset passphrase may work fine, but I much prefer what the OP here did.
$encrypted_file = "file.csv.pgp";
$path_to_file = $_SERVER["DOCUMENT_ROOT"]."/dir1/dir2";
$passphrase = "passphrase";
$command = "echo {$passphrase} | gpg --passphrase-fd 0 --batch --yes {$path_to_file}/{$encrypted_file}";
exec($command);
If successful, the decrypted file will be in the same directory, without the .pgp extension. So make sure it was successful...
$decrypted_file = str_replace(".pgp", "", $encrypted_file );
if (file_exists("{$path_to_file}/{$decrypted_file}")) {
echo "Successfully decrypted $encrypted_file to $decrypted_file";
}

How to encrypt a string with GnuPG?

How can I encrypt a given string using gpg from command line?
I have the public key stored in a file called pubkey.pub
I thought I could simply do it with something like that.
gpg --import "path/to/pubkey.pub" --encrypt "my string to encrypt"
But this won't work.
Background: I have to use the PHP exec command to encrypt given text, because I don't have the PHP module itself installed on the server.
gpg reads from stdin while encrypting, thus run
echo "my string to encrypt" | gpg --encrypt
gpg --import imports key material to GnuPG's keystore, where it remains; thus you only have to call it once (and it is a rather slow operation, as it might trigger updating your trust database).

Apache user account passwordless access to the server - Ubuntu

I have the same issue which is in this question. If I explain it again, I can use rsync to sync my local data with the server without password(I used SSH keys). But when I use exec() function in PHP, it doesn't work.
The person who has asked the above question has given the answer by himself. He says it can be done by allowing the Apache user account passwordless access to the serve. So my question is how do I provide Apache user account passwordless access to the server?
My PHP code is :
echo exec('rsync -aze --progress --size-only /var/tmp/src/File01 serveruser#mycloud.com.lk:/var/tmp/dest/File01');
PS: I logged into my machine using my typical user account (Let say username is 'bob'), and generated ssh keys using ssh-keygen -t rsa . Then bob has passwordless access to server.
But,When I run PHP command, it runs in Apache under mod_php and Usually Apache is running as its own user account, independent from the real-world people who use the server. Therefore my generated keys are not available to PHP inside Apache.
Therefore I tried to login as Apache user (I think it is www-data). But most of the articles says www-data doesn't have a password by default and cannot login as www-data.
Thank you.
The problem was the Apache user cannot access my keys. Therefore I had to generate SSH keys for the Apache user (it's www-data) although it was not so secure. First login as root.
mkdir /var/www/.ssh
chown -R www-data:www-data /var/www/.ssh
Now generate SSH keys as following. It will save your private key and public key in /var/www/.ssh folder:
sudo -u www-data ssh-keygen -t rsa
Now you should get something like this:
root#sampath-Vostro-1520:/var/www/.ssh# sudo -u www-data ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/var/www/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /var/www/.ssh/id_rsa.
Your public key has been saved in /var/www/.ssh/id_rsa.pub.
The key fingerprint is:
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx www-data#machine-Vostro-1520
The key's randomart image is:
+--[ RSA 2048]----+
| ...o...o..|
| o.. o|
| + .. .+o|
| . .*o+o|
| ++ S ..B..|
| o . E + |
| . . o o |
| . . |
| |
+-----------------+
Now copy your public key to the remote server:
sudo -u www-data ssh-copy-id -i /var/www/.ssh/id_rsa.pub username#myserver.com
Now this should work. :-)
<?php
$c='rsync -azv /source/folder/path/ username#myserver.com:/destination/folder/path';
exec($c,$data);
print_r($data);
?>
Normally your key is loaded via an SSH agent making it automatically available, instead of using this you can manually specify an identity file. If you generate a key to use, as long as it's readable by apache then it can be used.
Rsync doesn't let you specific the identiy file directly but you can pass parameters to the underlying SSH call:
echo exec('rsync -az -e "ssh -i /var/www/key.pri" --progress --size-only /var/tmp/src/File01 serveruser#mycloud.com.lk:/var/tmp/dest/File01');

PHP / Bash: Creating PPK out of OpenSSH Key with passphrase

I would like to create a php script that creates keys for ssh-authentication.
I've started with a
exec("ssh-keygen -b 1024 -t dsa -N *pwd* -f *path-to-file* -q");
to create the private and public-key-pair. No problem till here ;)
Now I've to convert the OpenSSL-Key to the ppk-format of PuTTY (in the cmd, not in the GUI). If anyone have an Idea on how to manage that, please let me know.
Thanks
If you were working with RSA keys you could do this (requires phpseclib):
<?php
include('Crypt/RSA.php');
$rsa = new Crypt_RSA();
$rsa->setPassword('password');
$rsa->loadKey('...');
//$rsa->setPassword(); // clear the password if there was one
echo $rsa->getPrivateKey(CRYPT_RSA_PRIVATE_FORMAT_PUTTY);
?>
You have not specified, what OS you run at. On *nix, you can use PuTTYgen (from PuTTY):
puttygen openssl-key -o mykey.ppk
For details see: https://linux.die.net/man/1/puttygen
On Windows, PuTTYgen is a GUI application only. Though, you can use WinSCP, it has PuTTYgen-compatible command-line interface:
winscp.com /keygen openssl-key -o mykey.ppk

how to use php call linux GPG encrypt file with a passphase

I have a task which need to
use gpg to encrypt the upload file in php
my code is:
("echo '1234' | gpg --passphrase-fd 0 -c /path/aaa.jpg ");
it works by paste the code in linux
but not work by php any solution
You need to use gnupg_decypt() to decrypt the text.

Categories