OpenSSL req won't work on PHP Shell - php

I've been searching for the solution of my problem which is about OpenSSL. I'm using shell_exec() to run shell promts. For example:
shell_exec("openssl genrsa -out myprvkey.pem 1024"); works fine, and generates myprvkey.pem.
However,
shell_exec("openssl req -new -key myprvkey.pem -x509 -days 365 -out mypubcert.pem"); isn't working without giving any errors.
Am I doing something wrong? Thanks. PS: Please remind me if I'm missing something.
OpenSSL Version: 268439647

Looks like you're trying to create a CSR? If so you can do so using phpseclib, a pure PHP CSR implementation, pretty easily. Here's an example that creates a new RSA key and a new CSR:
<?php
include('File/X509.php');
include('Crypt/RSA.php');
$privKey = new Crypt_RSA();
extract($privKey->createKey());
$privKey->loadKey($privatekey);
$x509 = new File_X509();
$x509->setPrivateKey($privKey);
$x509->setDNProp('id-at-organizationName', 'phpseclib demo cert');
$csr = $x509->signCSR();
echo $x509->saveCSR($csr);
?>
Here's an example that creates a new CSR utilizing an existing RSA key:
<?php
include('File/X509.php');
include('Crypt/RSA.php');
$privKey = new Crypt_RSA();
$privKey->loadKey('...');
$x509 = new File_X509();
$x509->setPrivateKey($privKey);
$x509->setDNProp('id-at-organizationName', 'phpseclib demo cert');
$csr = $x509->signCSR();
echo $x509->saveCSR($csr);
?>
(the only diff is that loadKey is being passed a string [which could be populated via file_get_contents or just directly inputted] instead of the output of extract($rsa->createKey()))

Related

How to encrypt a string using RSA algorithm and PKCS1_PADDING not OAEP and print the encrypted string in PHP

Here is the code I am using but I keep getting a blank echo. How can I echo the encrypted text.
include('Crypt/RSA.php');
$rsa = new Crypt_RSA();
$rsa->loadKey(file_get_contents('privatekey.txt'));
$rsa->loadKey($rsa->getPublicKey());
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
echo $rsa->encrypt('1234567890');

How i can create a self-signed certificate using phpseclib

How i can create a self-signed certificate using phpseclib from a existing .csr file, only i can use a .csr file.
I've read the manual and the method use a private key, but in my assignment i only can use a .csr file.
I hope you can help me.
Here's my code:
<?php
include('File/X509.php');
include('Crypt/RSA.php');
if ($_FILES["file"]["error"] > 0)
{
echo "Return Code: " . $_FILES["file"]["error"] . "<br>";
}
else
{
//This is the content of the file
$csr = file_get_contents($_FILES["file"]["name"]);
}
// create private key / x.509 cert for stunnel / website
$privKey = new Crypt_RSA();
extract($privKey->createKey());
$privKey->loadKey($privatekey);
$pubKey = new Crypt_RSA();
$pubKey->loadKey($publickey);
$pubKey->setPublicKey();
$subject = new File_X509();
$subject->loadCSR('...'); // see csr.pem
// calling setPublicKey() is unnecessary when loadCSR() is called
$issuer = new File_X509();
$issuer->setPrivateKey($privKey);
$issuer->setDN($subject->getDN());
$x509 = new File_X509();
//$x509->setStartDate('-1 month'); // default: now
//$x509->setEndDate('+1 year'); // default: +1 year
$result = $x509->sign($issuer, $subject);
echo "the stunnel.pem contents are as follows:\r\n\r\n";
echo $privKey->getPrivateKey();
echo "\r\n";
echo $x509->saveX509($result);
echo "\r\n";
?>
You need a private key, plain and simple. Otherwise, what are you going to sign it with? The signature field of an X.509 cert is mandatory.
I mean, if all you want is a public key, you don't need to bother with the X.509 overhead. You can just pony up a public key that looks like this:
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0
FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/
3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQAB
-----END PUBLIC KEY-----
But X.509 is more than just a public key - it's a signed public key. Technically, a CSR is, too, but CSR's are always self-signed whereas X.509 certs can be signed by anyone.

openssl: how can i get public key from modulus

I generate a pair of keys using openssl:
shell> ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/mike/.ssh/id_rsa): /path/to/test_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /path/to/test_rsa.
Your public key has been saved in /path/to/test_rsa.pub.
And then, I generate modulus from private key:
shell> openssl rsa -in /path/to/test_rsa -noout -modulus > /path/to/modulus.txt
Now, is there any way to get test_rsa.pub(public key) just from modulus?
You can get the public key in a more standardized format using phpseclib, a pure PHP RSA implementation. eg.
<?php
include('Crypt/RSA.php');
$modulus = 'yEQs2LxSHBZgZCH0rRQQy9kmry8g2tNhQL1B9f5azNz9Ce9pXPgSRjVUo1B9Ggb/FK3jy41wWd2IfS6rse3vBzRsabMj29CVODM/19yZPmwEmjJHCgYd+AA2qweKZanDp4FLsSw/kyV5WoPN16GHEMLmLGkJFNIWtzzH5jV+S80=';
$exponent = 'AQAB';
$rsa = new Crypt_RSA();
$modulus = new Math_BigInteger(base64_decode($modulus), 256);
$exponent = new Math_BigInteger(base64_decode($exponent), 256);
$rsa->loadKey(array('n' => $modulus, 'e' => $exponent));
$rsa->setPublicKey();
echo $rsa->getPublicKey();

phpseclib signing CSR with own CA

I want to sign a CSR with my CA. I took some parts of this code from phpseclib: X.509 Examples
<?php
include('File/X509.php');
include('Crypt/RSA.php');
$c = $_POST['csr'];
$CAPrivKey = new Crypt_RSA();
$CAPrivKey->setPassword('PrivatePassword');
$CAPrivKey->loadKey("-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,47EF178926906B55
lVtuTcJ1etpRaUT9086Vm5dsop8o5D92VVubcyhI268ZG4frRCBR4yuyORp+zdS2
[...]
gyx636VRV7aekLc6IFHJ56MzZRA/23izSooWqAJLTGEBrc4CWuodj9cc/+p3+9zC
-----END RSA PRIVATE KEY-----
");
$issuer = new File_X509();
$issuer->setPrivateKey($CAPrivKey);
$issuer->loadX509("-----BEGIN CERTIFICATE-----
MIIK0zCCBrugAwIBAgIJAPzTFDuzmcUcMA0GCSqGSIb3DQEBBQUAMIGhMQswCQYD
[...]
6F5Ji6w2IfD6xFhgvyTmqYgsae3+DEX6TAJosaI0EJQz6vYeubQb
-----END CERTIFICATE-----
");
$subject = new File_X509();
$subject->loadCSR($c);
$x509 = new File_X509();
$x509->setStartDate('-1 month');
$x509->setEndDate('+1 year');
$result = $x509->sign($issuer, $subject);
echo $x509->saveX509($result);
?>
In $csr I've got CSR formatted this way:
-----BEGIN CERTIFICATE REQUEST-----
MIGYMIGFAgAwbzELMAkGA1UEBgwCUEwxCjAIBgNVBAgMAS4xETAPBgNVBAcMCExlb2Frd2RhMQow
[...]
dGVzdC5wbDAQMAsGCSqGSIb3DQEBAQMBADALBgkqhkiG9w0BAQUDAQA=
-----END CERTIFICATE REQUEST-----
This code gives me error: Fatal error: Maximum execution time of 30 seconds exceeded in D:\wamp\www\Math\BigInteger.php on line 1659
How many bits is the key? Do you have gmp or bcmath or openssl installed? Phpseclib uses each of those to speed things up if they're available and if not it'll use it's own internal implementation which is the slowest. Per the math_biginteger benchmarks on phpseclib.sourceforge.net the pure php implementation on older versions of php will take a long time even with a 2048 bit key.

openssl command in php

I want to generate example.com.crt and example.com.pem using php. The Linux command to get the files is given:
openssl req -newkey rsa:2048 -new -x509 -days 3652 -nodes
-out example.com.crt -keyout example.com.pem
I want to get the two file contents in two string in php. What is the php equivalent code for this?
UPDATE: Please don't ask to execute the Linux command.
here another command:
<?php
// generate 2048-bit RSA key
$pkGenerate = openssl_pkey_new(array(
'private_key_bits' => 2048,
'private_key_type' => OPENSSL_KEYTYPE_RSA
));
// get the private key
openssl_pkey_export($pkGenerate,$pkGeneratePrivate); // NOTE: second argument is passed by reference
// get the public key
$pkGenerateDetails = openssl_pkey_get_details($pkGenerate);
$pkGeneratePublic = $pkGenerateDetails['key'];
// free resources
openssl_pkey_free($pkGenerate);
// fetch/import public key from PEM formatted string
// remember $pkGeneratePrivate now is PEM formatted...
// this is an alternative method from the public retrieval in previous
$pkImport = openssl_pkey_get_private($pkGeneratePrivate); // import
$pkImportDetails = openssl_pkey_get_details($pkImport); // same as getting the public key in previous
$pkImportPublic = $pkImportDetails['key'];
openssl_pkey_free($pkImport); // clean up
// let's see 'em
echo "\n".$pkGeneratePrivate
."\n".$pkGeneratePublic
."\n".$pkImportPublic
."\n".'Public keys are '.(strcmp($pkGeneratePublic,$pkImportPublic)?'different':'identical').'.';
?>
You could use phpseclib, a pure PHP X.509 implementation:
http://phpseclib.sourceforge.net/x509/examples.html#selfsigned
<?php
include('File/X509.php');
include('Crypt/RSA.php');
// create private key / x.509 cert for stunnel / website
$privKey = new Crypt_RSA();
extract($privKey->createKey());
$privKey->loadKey($privatekey);
$pubKey = new Crypt_RSA();
$pubKey->loadKey($publickey);
$pubKey->setPublicKey();
$subject = new File_X509();
$subject->setDNProp('id-at-organizationName', 'phpseclib demo cert');
//$subject->removeDNProp('id-at-organizationName');
$subject->setPublicKey($pubKey);
$issuer = new File_X509();
$issuer->setPrivateKey($privKey);
$issuer->setDN($subject->getDN());
$x509 = new File_X509();
//$x509->setStartDate('-1 month'); // default: now
//$x509->setEndDate('+1 year'); // default: +1 year
$result = $x509->sign($issuer, $subject);
echo "the stunnel.pem contents are as follows:\r\n\r\n";
echo $privKey->getPrivateKey();
echo "\r\n";
echo $x509->saveX509($result);
echo "\r\n";
?>
That'll create a private key and a self-signed X.509 cert (as your CLI example does) with the private keys corresponding public key.
Execute the command with the exec() or system() function, then read the output files with file_get_contents().
There is OpenSSL extension to PHP, you should check if it is not enough for you as it would be better to use it insteaf of exec():
http://php.net/manual/en/book.openssl.php
Perhaps it's not the finest solution, but you can use exec() and file_get_contents(), something like:
exec("openssl req -newkey rsa:2048 -new -x509 -days 3652 -nodes -out example.com.crt -keyout example.com.pem");
$crtFile = file_get_contents("example.com.crt");
$pemFile = file_get_contents("example.com.pem");
Be aware file permissions and obviously file paths. Better if you add some error handling around these commands.
Read more: http://php.net/manual/en/function.exec.php
And: http://php.net/manual/en/function.file-get-contents.php

Categories