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

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));

Related

Replace .env parameter with content of a file

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

How do I make it this OpenSSL command starts working?

My OpenSSL command is not working, which I am running through php's exec() function.
The error that is outputted is "1".
OpenSSL is enabled and working.
Here is the command:
$openssl_cmd = "($OPENSSL smime -sign -signer $MY_CERT_FILE -inkey $MY_KEY_FILE " .
"-outform der -nodetach -binary <<_EOF_\n$data\n_EOF_\n) | " .
"$OPENSSL smime -encrypt -des3 -binary -outform pem $PAYPAL_CERT_FILE";
exec($openssl_cmd, $output, $error);
I am running the latest version of XAMPP and running on Windows 10.
Thanks in advance!
EDIT:
Here is the full command when outputted as die($openssl_cmd); in php:
(C:/xampp/apache/bin/openssl.exe smime -sign -signer C:\xampp\[redacted]\paypal\pubcert.pem -inkey C:\xampp\[redacted]\paypal\prvkey.pem -outform der -nodetach -binary <<_EOF_ cmd=_xclick amount=[redacted] item_number=[redacted] discount_rate=0 item_name=[redacted] notify_url=https://www.REDACTED.net/paypal/ipn business=REDACTED cert_id=REDACTED currency_code=USD no_shipping=1 bn=domain.PHP_EWP2 _EOF_ ) | C:/xampp/apache/bin/openssl.exe smime -encrypt -des3 -binary -outform pem C:\xampp\[redacted]\paypal\paypal_cert.pem
EDIT:
I am using https://www.stellarwebsolutions.com/en/articles/paypal_button_encryption_php.php as a guide.
To execute a Linux-style command in Windows, something that uses piping and file redirection, it is possible to run the command using the Windows PowerShell.
For example, in this case, you would execute it via the PowerShell by executing something similar to this:
poewrshell -Command "(C:/xampp/apache/bin/openssl.exe smime -sign -signer C:\xampp\[redacted]\paypal\pubcert.pem -inkey C:\xampp\[redacted]\paypal\prvkey.pem -outform der -nodetach -binary <<_EOF_ cmd=_xclick amount=[redacted] item_number=[redacted] discount_rate=0 item_name=[redacted] notify_url=https://www.REDACTED.net/paypal/ipn business=tomekandres#live.ca cert_id=REDACTED currency_code=USD no_shipping=1 bn=domain.PHP_EWP2 _EOF_ ) | C:/xampp/apache/bin/openssl.exe smime -encrypt -des3 -binary -outform pem C:\xampp\[redacted]\paypal\paypal_cert.pem"

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?

OpenSSL SHA1 Hash doesn't match

I'm generating a SHA1 hash via OpenSSL via the commandline with the following command:
echo -n "test" | openssl dgst -sha1 -sign private.pem | openssl enc -base64
The output is:
mTuk4MicnS1Xn9BB4wed6pWe62CGDgj6imaOp9f3spiRo/W88WNac7sMkAYl37ruh82mbREbEzsFwCCdhO3MpGh/tyhb+2vx59tta1GTp5Nhb8PlnFL20Zh8QUrv6WrgvsI8z4IPG4KXCJw++7hBQHcnxa8dT5EMn1OW72MumG8=
when I execute the same command via PHP with exec() I get a different output:
YDGDpc0nC1uaFBO28uepQ/8hMhqoUhXIhqb0UTVCHA2oqWI7PeYyHBB1tmvQ8iqo/ZJzvkNxAruy6T67rdpz/4hyKh6hRxGvYNStteqv/Cn04yiSlgidiHnN2x5aoI6GdE/c0haiE/WmJlFTOcQdPztsQWOk2QUzWdwDmO0OjqE=
WHY?
both scripts run via the same user, As the PHP Script is run as "nobody" I have logged in via the shell as nobody and executed it... no dfference
Using the full path fixed the problem!

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