I have generated a SSH key with PHP OpenSSL:
$rsaKey = openssl_pkey_new(array(
'private_key_bits' => 4096,
'private_key_type' => OPENSSL_KEYTYPE_RSA,
));
$privKey = openssl_pkey_get_private($rsaKey);
openssl_pkey_export($privKey, $pem);
This results in $pem looking like this:
-----BEGIN PRIVATE KEY-----
MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQC8ggt6rVHYnqNP
...
e95+EXbPc6THyWt9pgwOsJltpylIYG4=
-----END PRIVATE KEY-----
But I cannot authenticate using this key. Before I can use it, I have to convert it using this command:
openssl rsa -in xxx.key -outform pem > xxx.key2
The result of the conversion is this:
-----BEGIN RSA PRIVATE KEY-----
MIIJKQIBAAKCAgEAvIILeq1R2J6jT+xjlK5NrOqFZTOJ4PByvgPQNbb2Kp7c3W15
...
o1t2KBkaSoR+JyOPOZakq5BLv8lgD3vefhF2z3Okx8lrfaYMDrCZbacpSGBu
-----END RSA PRIVATE KEY-----
Both are PEM format, but the second is a RSA private key. With the second, PHP can login. So I need a key that starts with RSA PRIVATE KEY, not just PRIVATE KEY. How can I create this with PHP and OpenSSL PHP implementation?
So, these are two different key types. You're looking for PKCS #1, but getting PKCS #8.
This appears to be related to the version of OpenSSL that PHP uses. Versions since 1.0 create a PKCS #8 file, and there's nothing the PHP developers want to do about it. The same issue arises when doing it from the command line with this command:
openssl req -new -keyout mykey.key -out mycertreq.csr -nodes -sha1 -newkey rsa:2048
You can try using an external library called phpseclib, though I haven't tried it myself:
<?php
include('Crypt/RSA.php');
$rsa = new Crypt_RSA();
$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_OPENSSH);
$result = $rsa->createKey();
echo $result["privatekey"];
?>
Related
I generate private.key with:
openssl genrsa -out private.key 2048.
From private key I generate public key with:
openssl rsa -in private.key -pubout -out public.key
With these keys oauth2 server creates authorization JWT
And I need that JWT payload contains issuer (iss).
On which step should I add it? And any ideas how to add it?
i tried to integrate bankID with my code but it does not work
this is the tutorial bankID tutorial
this api have ssl certification https://www.bankid.com/assets/bankid/rp/FPTestcert2_20150818_102329.pfx
can any one help me to integrate this api with php
this is my code
try {
$client = new SoapClient( 'https://appapi.test.bankid.com/rp/v4?wsdl', array( "local_cert" => "/certname.pem" ) );
} catch (Exception $e) {
echo json_encode( array( "result" => false, "reason" => $e->getMessage() ) );}
and because the ssl is pfx i convert it by useing openssl as
openssl pkcs12 -in FPTestcert2_20150818_102329.pfx -nocerts -out key.pem -nodes
openssl pkcs12 -in FPTestcert2_20150818_102329.pfx -nokeys -out cert.pem
openssl rsa -in key.pem -out server.key
Copy
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
section from server.key and
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
section from cert.pem and put them into new certname.pem file.
and this is the error
SOAP-ERROR: Parsing WSDL: Couldn't load from 'link' : failed to load external entity
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
When I'm creating private key strings with the following PHP code (and same config-parameter), they are enclosed between different strings:
$configs = array('config' => 'OpenSSL.cnf',
'digest_alg' => 'sha1',
'x509_extensions' => 'v3_ca',
'req_extensions' => 'v3_req',
'private_key_bits' => 2048,
'private_key_type' => OPENSSL_KEYTYPE_RSA,
'encrypt_key' => false,
'encrypt_key_cipher' => OPENSSL_CIPHER_3DES);
$privateKeyResourceId = openssl_pkey_new($this->configs);
openssl_pkey_export($privateKeyResourceId, $privateKeyString);
On Linux the $privateKeyString looks like this:
-----BEGIN PRIVATE KEY-----NBgkqhkiG9w0BAQE....ASDFasjkfa-----END PRIVATE KEY-----
On Windows the $privateKeyString looks like this:
-----BEGIN RSA PRIVATE KEY-----NBgkqhkiG9E....ASDFasjkfa-----END RSA PRIVATE KEY-----
When I copy the Windows private key string to Linux it works until I remove the 'RSA' from the start/end (same behavior vice versa). Why is this?
This is a differece between openssl versions not PHP. The following openssl command creates different key headers/footers between openssl versions 0.9.x and 1.0.0x:
openssl req -new -keyout mykey.key -out mycertreq.csr -nodes -sha1 -newkey rsa:2048
For version 0.9.x, the key header/footer is:
-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----
For version 1.0.0x, the key header/footer is:
-----BEGIN PRIVATE KEY-----
-----END PRIVATE KEY-----
For the later version of openssl, I have to run the key file through the following command to make it compatible with the older default:
openssl rsa -in mykey.key -text > mykey.pem
The "mykey.pem" file then has the header/footers (and format) that is compatible with AWS and like services.
According to a user note php.net this is a known issue:
Please take note that older versions of PHP/OpenSSL exports the RSA private key with '-----BEGIN RSA PRIVATE KEY-----' PEM tag, which includes just the privateKey field, thus omitting the version and privateKeyAlgorithm fields.
The effect of that would be that if you're converting it to DER, and
then back to PEM, but using '-----BEGIN PRIVATE KEY-----' PEM tag,
that the openssl_pkey_get_privatekey() function will fail!Senthryl's
code can be used to prefix the PEM encoded data with the version and
privateKeyAlgorithm fields again.
The newer PHP/OpenSSL versions exports the RSA private key with
'-----BEGIN PRIVATE KEY-----' PEM tag, which includes the version and
privateKeyAlgorithm fields.
I noticed these differences between my two servers:
PHP Version 5.3.3 (OpenSSL 1.0.0a-fips 1 Jun 2010) on Fedora Core 12 x64
PHP Version 5.2.9 (OpenSSL 0.9.8g 19 Oct 2007) on Fedora Core 10 x64
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.