Replace .env parameter with content of a file - php

I want to replace a parameter in my .env with content of a file when installing dependencies.
I've this in my docker-compose.yml under the specific php-container:
command:
- /bin/sh
- -c
- |
date +%s | sha256sum | base64 | head -c 32 > passphrase.txt
openssl genrsa -out config/jwt/private.pem -aes256 -passout file:passphrase.txt 4096
openssl rsa -passin file:passphrase.txt -pubout -in config/jwt/private.pem -out config/jwt/public.pem
composer install
php bin/console --no-interaction doctrine:migrations:migrate
Now when composer runs, the parameter of JWT_PASSPHRASE should be replaced with the content of passphrase.txt:
###> lexik/jwt-authentication-bundle ###
# Key paths should be relative to the project directory
JWT_PRIVATE_KEY_PATH=config/jwt/private.pem
JWT_PUBLIC_KEY_PATH=config/jwt/public.pem
JWT_PASSPHRASE=???
JWT_TOKEN_TTL=3600
###< lexik/jwt-authentication-bundle ###
Is that possible?
Best,
Christian

I solved this just by exporting the JWT_PASSPHRASE. I do not need to write the passphrase into a file.
export JWT_PASSPHRASE=$(date +%s | sha256sum | base64 | head -c 32)
openssl genrsa -out config/jwt/private.pem -aes256 -passout pass:${JWT_PASSPHRASE}
openssl rsa -passin pass:${JWT_PASSPHRASE} -pubout -in ./config/jwt/private.pem -out ./config/jwt/public.pem

Related

PHP equivalent of openssl dgst -sha1 -hmac KEY -binary

I try to implement this bash command in PHP without success :
password='echo -en "$date" | openssl dgst -sha1 -hmac $apiKey -binary | openssl enc -base64'
I tried the openssl_digest and openssl_encrypt without success.
I don't understand the order of the parameters...
Could you help me to generate the expected command in PHP ?
Thanks for your help !
The bash command :
password='echo -en "$date" | openssl dgst -sha1 -hmac $apiKey -binary | openssl enc -base64'
can be interpreted in PHP as follows :
$password = base64_encode(hash_hmac('sha1', $date, $apiKey, true));

Encrypt file using certificate resulting in 'Expecting PUBLIC KEY' [duplicate]

I am using the below openssl command for storing my public key into a .pem file.
openssl> x509 -in E:/mycert.pem -pubkey -out E:/mypubkey.pem
But when i try to use this command, it is storing the whole certificate info in the mypubkey.pem file.
I have seen that i can save my public key using
openssl> x509 -pubkey -noout -in cert.pem > pubkey.pem
But it is throwing an error. I can't use ">" operator.
There are a couple ways to do this.
First, instead of going into openssl command prompt mode, just enter everything on one command line from the Windows prompt:
E:\> openssl x509 -pubkey -noout -in cert.pem > pubkey.pem
If for some reason, you have to use the openssl command prompt, just enter everything up to the ">". Then OpenSSL will print out the public key info to the screen. You can then copy this and paste it into a file called pubkey.pem.
openssl> x509 -pubkey -noout -in cert.pem
Output will look something like this:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAryQICCl6NZ5gDKrnSztO
3Hy8PEUcuyvg/ikC+VcIo2SFFSf18a3IMYldIugqqqZCs4/4uVW3sbdLs/6PfgdX
7O9D22ZiFWHPYA2k2N744MNiCD1UE+tJyllUhSblK48bn+v1oZHCM0nYQ2NqUkvS
j+hwUU3RiWl7x3D2s9wSdNt7XUtW05a/FXehsPSiJfKvHJJnGOX0BgTvkLnkAOTd
OrUZ/wK69Dzu4IvrN4vs9Nes8vbwPa/ddZEzGR0cQMt0JBkhk9kU/qwqUseP1QRJ
5I1jR4g8aYPL/ke9K35PxZWuDp3U0UPAZ3PjFAh+5T+fc7gzCs9dPzSHloruU+gl
FQIDAQAB
-----END PUBLIC KEY-----
if it is a RSA key
openssl rsa -pubout -in my_rsa_key.pem
if you need it in a format for openssh , please see Use RSA private key to generate public key?
Note that public key is generated from the private key and ssh uses the identity file (private key file) to generate and send public key to server and un-encrypt the encrypted token from the server via the private key in identity file.
I am not sure why the other answers have such high upvotes. They do not solve the two problems presented in the question. A key point to the problem is the openssl command interpreter is being used and not the shell prompt.
Problem #1 - the certificate is written with the public key.
I am using the below openssl command for storing my public key into a
.pem file.
openssl> x509 -in E:/mycert.pem -pubkey -out E:/mypubkey.pem But when
i try to use this command, it is storing the whole certificate info in
the mypubkey.pem file.
The solution is to add the command argument -noout.
Problem #2 - ">" operator is not supported:
openssl> x509 -pubkey -noout -in cert.pem > pubkey.pem
But it is throwing an error. I can't use ">" operator.
The solution is to add the -out <filename> command parameter.
Solution:
openssl> x509 -pubkey -in cert.pem -noout -out pubkey.pem

Issue with shell script called from PHP

TLDR;
I have a shell script which works fine when run from the command line, but not if called from within a PHP script (accessed via web).
In both cases, the calling user is www-data.
The line failing is this:
openssl genrsa -des3 -out certs/$PCODE.key -passout env:PASSPHRASE 2048
Why is this happening? How can I debug it?
Full story
I have the following script which is a slightly modified version of this gist for generating self-signed SSL certs.
When I run it from the terminal as www-data it works ok and generates the key files, the CSR and the SSL cert file. But when I call the script from within a PHP script, it outputs an error and no files are generated. What is causing the failure? How can I debug this?
From terminal:
me#machine$ sudo su www-data
www-data#machine$ ./gencert.sh acme
www-data will generate an SSL cert for acme.dev
Command after line 32 executed oK
Passphrase expoted as I7gOnWxWd0hOk38Zu ... FbxL3K3Rzlv
Generating RSA private key, 2048 bit long modulus
..............................................+++
.................+++
e is 65537 (0x10001)
Command after line 49 executed oK
Command after line 54 executed oK
Command after line 65 executed oK
writing RSA key
Command after line 69 executed oK
Signature ok
subject=/C=IR/ST=Alborz/.../emailAddress=noreply#acme.dev
Getting Private key
Command after line 74 executed oK
Resulting files:
certs/acme.key.org
certs/acme.key
certs/acme.csr
certs/acme.crt
From PHP:
$r = `/var/www/testbench/pm/shell/gencert.sh acme`;
echo $r;
No files are generated and the output is this:
www-data will generate an SSL cert for acme.dev
Command after line 32 executed oK
Passphrase expoted as 1Fd1seZoe2XF ... oSmQFJdVpdwOeTo2CK5VjLxp
Error. Return value = 1 after line 49
The line returning 1 is this:
openssl genrsa -des3 -out certs/$PCODE.key -passout env:PASSPHRASE 2048
Here is the modified shell script:
#!/bin/bash
# Bash shell script for generating self-signed certs. Run this in a folder, as it
# generates a few files. Large portions of this script were taken from the
# following artcile:
#
# http://usrportage.de/archives/919-Batch-generating-SSL-certificates.html
# https://deliciousbrains.com/ssl-certificate-authority-for-local-https-development/
# Additional alterations by: Brad Landers
# Date: 2012-01-27
# Script accepts a single argument, the fqdn for the cert
PCODE="$1"
if [ -z "$PCODE" ]; then
echo "Usage: $(basename $0) <PCODE>"
exit 11
fi
THE_USER="$(whoami)"
echo "$THE_USER will generate an SSL cert for $PCODE.dev"
fail_if_error() {
[ $1 != 0 ] && {
echo -n "Error. Return value = $1 after line $LASTLINE"
unset PASSPHRASE
exit 10
}
echo "Command after line $LASTLINE executed oK"
}
# Generate a passphrase
LASTLINE="${LINENO}"
export PASSPHRASE=$(head -c 500 /dev/urandom | tr -dc a-z0-9A-Z | head -c 128; echo)
fail_if_error $?
echo -n "Passphrase expoted as "
printenv PASSPHRASE
# Certificate details; replace items in angle brackets with your own info
subj="
C=IR
ST=Alborz
O=ACME
localityName=Karaj
commonName=*.$PCODE.dev
organizationalUnitName=WebAdmin
emailAddress=noreply#$PCODE.dev
"
LASTLINE="${LINENO}"
# Generate the server private key
openssl genrsa -des3 -out certs/$PCODE.key -passout env:PASSPHRASE 2048
fail_if_error $?
LASTLINE="${LINENO}"
# Generate the CSR
openssl req \
-new \
-batch \
-subj "$(echo -n "$subj" | tr "\n" "/")" \
-key certs/$PCODE.key \
-out certs/$PCODE.csr \
-passin env:PASSPHRASE
fail_if_error $?
LASTLINE="${LINENO}"
cp certs/$PCODE.key certs/$PCODE.key.org
fail_if_error $?
LASTLINE="${LINENO}"
# Strip the password so we don't have to type it every time we restart Apache
openssl rsa -in certs/$PCODE.key.org -out certs/$PCODE.key -passin env:PASSPHRASE
fail_if_error $?
LASTLINE="${LINENO}"
# Generate the cert (good for 10 years)
openssl x509 -req -days 3650 -in certs/$PCODE.csr -signkey certs/$PCODE.key -out certs/$PCODE.crt
fail_if_error $?
The command you want to execute has relative paths, eg: certs/$PCODE.key. When you exec the commands (via the backtick operator in this case), the paths are expanded relative to the PHP process' current working directory. This is rarely, if ever, the same path as your command shell uses.
To debug this, you can extend your actual command with strace, eg: strace openssl .... This will give you considerable diagnostics and, near the end, you'll see something along the lines of EPERM.
To fix this, you can either use chdir in your PHP to set the current working directory, or you can cd in your script, or your script can use absolute paths. I'd prefer the latter.

How to use signature algorithm SHA-1 in php function openssl_pkcs7_sign

Used this code to sign file, but with different OpenSSL versions, the different result, or SHA-1 or SHA-256 turns out. It is necessary to set SHA-1.
openssl_pkcs7_sign($inFilename, $outFilename, "file://".$publicCertFile, "file://privateCertFile", array(), PKCS7_DETACHED | PKCS7_BINARY | PKCS7_NOATTR);
Result:
MIME-Version: 1.0
Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha-256"; boundary="----592DF2A997B872976D85E98B5BC89799"
...
...
The algorithm of sha-256 was used.
Working OpenSSL command:
openssl smime -sign -md sha1 -in "INFILE.TXT" -inkey private.pem -signer public.pem -binary -outform DER -noattr > FILE.RSA
In command line it is possible to set algorithm and how to make it in PHP?

Failure to verify openssl signatures in PHP

If I use openssl to create a new key pair, use the private key to sign some data, and use the public key to verify the signature... it works.
$ openssl genrsa -out mykey.pem 1024
$ openssl rsa -in mykey.pem -pubout > mypubkey.pem
$ echo 'It could be bunnies' > file.txt
$ openssl rsautl -sign -in file.txt -inkey mykey.pem -out sig.txt
$ openssl rsautl -verify -in sig.txt -inkey mypubkey.pem -pubin
It could be bunnies
However, if I try to verify the signature using the openssl library in php it fails.
$pubkey = openssl_pkey_get_public(file_get_contents('/var/key/mypubkey.pem'));
$sig = file_get_contents('/var/key/sig.txt');
$data = file_get_contents('/var/key/file.txt');
$verifyResult = (openssl_verify($data, $sig, $pubkey) == 1);
Similar story with Crypt_RSA
$pubkey = file_get_contents('/var/test/mypubkey.pem');
$sig = file_get_contents('/var/test/sig.txt');
$data = file_get_contents('/var/test/file.txt');
$rsa = new Crypt_RSA();
$rsa->loadKey($pubkey);
$rsa->verify($data, $sig);
$verifyResult = $rsa->verify($data, $sig);
How do I get php to play nicely? These examples are simplified but accurate to my needs. In the real world I will only have the data, signature, and public key...
I was really hoping someone would chime in with a definitive answer on the public key question. Seems like it should work. However, in the meantime, I've switched from a public key to a self-signed certificate. The openssl library in PHP seems happy with extracting an acceptable public key from that. Which means the real problem (verifying signed data) is solved for me. Server clients will now have the data, signature, and x.509 certificate.
Here are the code snippet(s).
$ openssl genrsa -out server.key 4096
$ openssl req -new -key server.key -out server.csr
$ openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
$ openssl dgst -sha1 -sign server.key -out file.sha1 file.txt
...
$pubkey = openssl_pkey_get_public(file_get_contents('/var/key/server.crt'));
$sig = file_get_contents('/var/key/file.sha1');
$data = file_get_contents('/var/key/file.txt');
$verifyResult = (openssl_verify($data, $sig, $pubkey) == 1);
For phpseclib, try $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1) before calling $rsa->verify().

Categories