convert .key to .pem - php

I need to encrypt with private key and I'm attempting to do so with the following code:
$content = file_get_contents("file.key");
$plaintext = "14d9df79-8c4c-4380-8444-d31e1fd3f78a";
openssl_private_encrypt($plaintext, $encrypted, $content);
$transfer = base64_encode($encrypted);
echo "text encrypted is:" . $transfer; //encrypted string
I'm getting the error:
openssl_private_encrypt(): key param is not a valid private key in
Do I have to do something to the key file? It is binary.

First, try converting a key into PEM format using openssl:
openssl rsa -inform der -in file.key -outform pem -out filekey.pem
Next, extract the private key from the PEM file using openssl_pkey_get_private
$key = openssl_pkey_get_private(file_get_contents("filekey.pem"));
$plaintext = "14d9df79-8c4c-4380-8444-d31e1fd3f78a";
openssl_private_encrypt($plaintext, $encrypted, $key);
$transfer = base64_encode($encrypted);
echo "text encrypted is:" . $transfer; //encrypted string

I don't know of any x509 file format using a .key extension. There's pem (which is the format you need to load into openssl), DER (files may have .der, .crt or .cer extension) or PKCS#12 (.pfx .p12). It's probably DER or PKCS#12:
openssl pkcs12 -in file.key -out file.pem -nodes
...converts a PKCS#12 to file.pem,
openssl x509 -inform der -in file.key -out file.pem
...converts a DER file. They'll report an error if it's the wrong file format. OTOH you could just use the 'file' command to find out the file type. (this is assuming that you've got a Posix / Linux system - you didn't say).
Or you could just ask the person who gave it to you what format it is.

Solved
I just use the
openssl pkcs8 .....
command
hope this is useful to someone else

Related

Certificate not accepted. Unable to set private key file

I try to make a connection through SoapClient. I need a certificate for this. I received a .pfx certificate. I used the following command to create a .pem file.
openssl pkcs12 -in cert.pfx -out cert.pem -nodes
There is a password in the certificate so I need to enter it before I get the cert.pem file. So far so good, I think.
Now I try to connect to the WSDL service.
$url = "https://test.website.com/webservices/transfer.asmx?WSDL";
$cert = '/path/to/cert.pem';
$passphrase = "12345678";
$soapClient = new SoapClient($url, array('local_cert'=>$cert,'passphrase'=>$passphrase));
I get the following error:
(Warning) SoapClient::SoapClient(): Unable to set private key file `/var/www/vhosts/............./cert.pem'
I think the problem is the certificate. Is the way that I converted the .pfx to a .pem the correct way?
The problem you're running into is that a .pem certificate is always supposed to be an encrypted file. According to the OpenSSL docs for the pkcs12 command when you used -nodes it didn't encrypt anything, rather put each node into plain text, which caused the .pem certificate to be invalid and your SoapClient couldn't parse the invalid file.
To fix this, hopefully you haven't deleted the original cert.pfx, just re-convert it using this line:
openssl pkcs12 -in cert.pfx -out cert.pem -clcerts
and your cert.pem file will be correct.
Today I had this problem with an invalid Cert/Private combination, meaning the cert wasn't belonging to the specified key.
You can verify this problem using:
openssl rsa -noout -modulus -in server.key | openssl md5
openssl x509 -noout -modulus -in server.crt | openssl md5
key and cert should return the same checksum. If not, somebody has mixed up some files.
The same procedure works for CSRs as well:
# and for a CSR
openssl req -noout -modulus -in server.csr | openssl md5

Is it possible to convert .cer and a .key files to .pem by only using php openssl functions?

I already have converted a public key (.cer) and a private key (.key) to pem format but I had use the command lines to convert them as follows:
$openSSLpath = "c:\OpenSSL-Win64\bin\openssl.exe"; //Path to OpenSSL exe
$path = "c:\appserver\Apache2.2\htdocs\FIEL"; //Path to Project Folder
$rutaCer = $path.'\GAMA600504JP1.cer';
$rutaKey = $path.'\GAMA600504JP1.key';
$passwordKey = '12345678a';
$cmdKey = $openSSLpath." pkcs8 -inform DER -in ".$rutaKey." -passin pass:".$passwordKey." -out ".$rutaKey.".pem";
exec($cmdKey);
$cmdCer = $openSSLpath." x509 -inform DER -outform PEM -in ".$rutaCer." -pubkey -out ".$rutaCer.".pem";
exec($cmdCer);
This generates correctly the .pem files but I need to know if is it possible to do this by any other way using PHP. Note that I'm completely new to openSSL and this is the only way I've found to do it on PHP.
To do this I have to ensure that OpenSSL its properly located and installed on my server and in order to do the conversions to .pem I have to save the .cer and .key files temporarily in the server which its not recommended due to security reasons.
Is there any other way?
You can easily convert your der data to PEM by simple code.
$rutaCer = file_get_contents($path.'\GAMA600504JP1.cer');
$rutaKey = file_get_contents($path.'\GAMA600504JP1.key');
echo "-----BEGIN PRIVATE KEY-----\n" . chunk_split(base64_encode($rutaKey), 64, "\n") . "-----END PRIVATE KEY-----";
echo "-----BEGIN CERTIFICATE-----\n" . chunk_split(base64_encode($rutaCer), 64, "\n") . "-----END CERTIFICATE-----";
// Save anywhere
PHP has functions for exporting to PEM but there is problem with loading keys/certificates from binary DER format.
Another way can be use of phpsec library.

openssl_pkcs7_sign returns nothing while signing Passbook's pass file

openssl_pkcs7_sign('manifest.json', 'signature', $certdata, $privkey, array(), PKCS7_BINARY | PKCS7_DETACHED, 'AppleWWDRCA.pem');
It makes a empty signature file and no error message.
But I can use OpenSSL command line to make a right signature(uses same copy of WWDR, p12, pkpass files):
openssl smime -binary -sign -certfile AppleWWDRCA.pem -signer passcertificate.pem -inkey passkey.pem -in manifest.json -out signature -outform DER -passin pass:123123
Check the values of your $certdata and $privkey, if they are filenames, prefix with 'file://'.
As #Charles says, your error logs are the best place to look for clues as to why it is failing.
We used to use the following command, but after benchmarking we found exec was performing better.
openssl_pkcs7_sign(
"manifest.json",
"signature",
"file://" . $certdata,
array("file://" . $privkey, $keyPassword),
array(),
PKCS7_BINARY|PKCS7_NOATTR|PKCS7_DETACHED,
"/path/to/AppleWWDRACA.pem");

PHP determine type of SSL certificate

I have certificate that can see in browser - signed by VeriSign - G3
But when I try to read with openSSL(or in PHP) like pkcs12 or x509 or pkcs7 - error like:
openssl pkcs12 -in cert.to.test.cer -clcerts -nokeys -out mycert.crt
28685:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:tasn_dec.c:1306:
28685:error:0D06C03A:asn1 encoding routines:ASN1_D2I_EX_PRIMITIVE:nested asn1 error:tasn_dec.c:830:
28685:error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error:tasn_dec.c:749:Field=version, Type=PKCS12
What can be done to read parameters of certificate in PHP?
Thanks.
You can try
openssl x509 -in certificate.der -inform der -text -noout
May be it is DER encoded certificate

OpenSSL PHP Function doesn't work

I'm looking for days how to translate this command to OpenSLL php function:
$ openssl pkcs8 -inform DER -in aaa010101aaa_CSD_01.key -out AAA010101AAA.key.pem
Enter Password: a0123456789
This work perfect, but I can't (I don't know) use the correct function of PHP OpenSSL
http://www.php.net/manual/es/ref.openssl.php
I have made this for .cer working perfect:
command : openssl x509 -inform DER -outform PEM -in aaa010101aaa_CSD_01.cer -out AAA010101AAA.cer.pem
PHP equivalent:
function der2pem($der_data) {
$pem = chunk_split(base64_encode($der_data), 64, "\n");
$pem = "-----BEGIN CERTIFICATE-----\n".$pem."-----END CERTIFICATE-----\n";
return $pem;
}
$fp = fopen("llaves/aaa010101aaa_CSD_01.cer", "r");
$priv_key = fread($fp, 8192);
fclose($fp);
echo der2pem($priv_key);
It's perfect, giving it to me the PEM. But doesn't work for the .key, just for the .cer, I obtain on OpenSSL this for .key using the funcion on PHP:
-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQDpmiW1q9gyzCFtMcbaFDJexk2IpLoTdNXg4ToGRZ/f+hIjmj3N
6ODWX1ARNFGYocEHf113GpW5Oe/mj6UqhBpiH4JRTNR4Udb8myJTArIlODynVHuI
UuyhKo7gbMbDdXjilTAYY2XWQuQ7aDtWwntUmNg4vAC/F3OtRz3+y9wM5QIDAQAB
AoGAfNkHomqvZ6a1jrh1wIPez8xID+mKEW/2BvQYoNWBNqFeJG0A7xWxZKEYF7nQ
ijSZB7rIZylsL8yJLL5E1c44koc+2+S6OF6gcWujcLR5UFRIZscxo0e1ro30wSTy
MBcdBeWASbaEy7+7MF46W0hAhBE7b49JUmduz1fBjtNNeoECQQD3VbNAsbf/90Vw
ZVexUXWNquwPsAZjmdpL1Te1RdC5txj2EbUdDPaaYC1cCXXjblf9rsyyViUowsNt
cnh92wSRAkEA8clIHObESiZZEndtmYuRlgLsX2Gr/qo30uAUurH7p8Q07SWOZCJk
OPJUhh2qanYZsnsOYHW+9Br5U6gDknxdFQJBALoua9nWLdDjnQTHdKSI0jmLIVmJ
wrV1GgsdfGrbHAzAlGye1bwBhxycK2jtwi0qYdgXngTcreop+hxIIAV1OdECQQC7
v7rZhnBhy8lax5Y5puEUBY0au7Nc+zyB6TLvjgmGSpt2krUxGGuOtM3hnuOX68Ek
kN2nFYeD8fYtecfcVenJAkEAxM+QzoVdJpw1/ijh+IfZ5eNhvMK2bj4De+/2Sx5K
ZZ9SiI7bRaOjBfvaI7AkeH0LpihURW12Zt7hZv8kC058Jg==
-----END RSA PRIVATE KEY-----
The same function on php give me:
-----BEGIN-----
MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIgkLCyAP9+nQCAggA MBQGCCqGSIb3DQMHBAgTJc/0zgL+tASCAoBHumtbuHsY5IevnUwr1Ha5P+S3RpVS 6iYvoOvKs5L6bPE+fjCkLxset0e68NcyXDw3WO/qzfGkFVGBnC90gekWUiS7/2pf ltPeKjo8Fw7T4CgVWhtnVdPZmJWihY52FuIQ2HuyQYzH8K/SnjYP4GBkJKpdPCjy JNzjspfJPoOlfdOkj7URwvKH5RjsLGYkopjtdaqxS2pFfz6PPCSiFMn+Jo9Vkjwv 3d1b3X2SoYuYhV2g3XgHWHBQNqoas8Blhcw8OYNlntxcaNnx3Eb9YcCWSmNj7l+c pibvosXzEqVoat6PsJyUVzJQZBao15PnI438qomkprsCy6EvFSSXuIunMH7nVIGH gcS0TRxYpXPHY3cdQOdsJtxb4Ny1aCJqLQkHs2jbiLZ5mu+rmQUil3tLxfRd4Bje AYA3T1e5VVVha97BmNQVTbNfxj9wWvkmrearxJXTvvnML4f0ma830S/1AGmCGLb/ A2KlqHq9RxqJn1SdOuYQbcQTeGe/JRVOaJVGUKxJ2vbwjB/35cmGNLKYj4faZZgy jYpC3BqVeDcPGlPuMnoNkgrBfLDgDX+JV6tqqT2uMo76Wp6xYKmM41jkO1IAWpHR /R7d3aG2psL0wKkFSEXWxhX3SRLdurVcFLv6E6bEPHqHJR4QrvF2OUwpDhOZz9F/ Lz935gz5MQNRuVRtAVBAa2ZmjRbdCboL/qiL2MKibZLNRmKy3dqRdPOmnlKKBR8d cYQc4YwRm5dWuObO2tY68R4H43g7shw+POKSzvSPhAkzRRGExONVDJ6Zg/0iAUNe 0xYlsqKJyCJ1fg/b1AuFyyAnOhCO9ywUGiK7t92pZRgmwxEfVBDRNcbA
-----END -----
Any ideas?
There's a library that allows just that. It is called Chilkat2. I used it to do the same in Python without console.
Right now I'm trying to remove this dependency in my library because it's closed source and it can't be installed through package managers, it must be installed manually with the website instructions.
It works pretty well, however, so here's how you would do it, assuming you have the .key file, the password, and Chilkat2 PHP Extension installed:
include("chilkat_9_5_0.php"); //whatever version you download
privateKey = new CkPrivateKey();
privateKey.LoadPkcs8EncryptedFile('path/to/private.key',password)
pemString = privateKey.getPkcs8Pem()
Note: I created this code with the documentation, but I have never used Chilkat2 with PHP.

Categories