Updated openssl and miracles started.
Two versions of openssl give different result.
openssl OpenSSL support => enabled
OpenSSL Library Version => OpenSSL **0.9.8y** 5 Feb 2013
OpenSSL Header Version => OpenSSL 0.9.8y 5 Feb 2013
openssl OpenSSL support enabled
OpenSSL Library Version OpenSSL **1.0.1f** 6 Jan 2014
OpenSSL Header Version OpenSSL 0.9.8y 5 Feb 2013
PHP code:
<?
$pkeyid = openssl_pkey_get_private("file:///certificate/bank_ee/private.key" , "dkcert");
openssl_pkey_export($pkeyid, $pkeyout);
var_dump($pkeyout);
from console (0.9.8y)
string(891) "-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQC3RTUIY+ACV0luhdub8BSLjeVGqKNxQ+5BwEFw1EsOSANo/2bJ
o8Wr1YO8u+cJ2vTw3dc2MHssRgIAmWeRNhjdtXj/dZv70KTXvvY1xV8asth7Cxni
I2dFzTbhc5FKkF6XvjsM83P3fjHyk0W5CvaUlqfo1I5Q/kZFf1bcXMMaCQIDAQAB
AoGBAKyXOkg6djz+IqM44AXMZCzAZkjSi4khJgE5ouc0pbI/UybQTuZZmtAl9TgJ
5Jw9XSpwYDoiEf0xuLUDwqrXvTWEetk+zPXCAZhJz+tlX1RsdJGq1Ubwj6odAham
dIYX2OwjBdrmw9MWPPNKzjQNXYUwptVAnn1nEFJFLp2wnuxZAkEA6h4zvcr7nJyN
erfE9m3/47vgpKrki3Iy+7C+GF5+auj86J5L7Pl3Rbj0WPjBha9axcrWRtpypQt2
ZG2IwZzGAwJBAMhmXHssXC7bxgz1uRWT2B647bnArAWM8z3qgIhKHVozKfIIpCMD
VzS26BQ3fEnQ02/Neg3djgnubI+4iy7JmAMCQQCqrIPp6+2MGbEmcow7Xqu6uP+m
7BKa+hDi3dFncJPWmq2tY6FUS/VAtfokVoy2ScTyBtI5aw1C9t1Dj3qwMvtDAkB6
KzT7/jogcujVI8P2rI/XguOiFxyHsbrkJx6+d3hXcdODctMlaTbzswHeuUiy83TC
tuBOrZ+W3Fwgbd+j4VAjAkEAiW5FWW4R9ixUgTrVXqOgdR+T8LNL4qMNu7x/EYkr
u1z8Pou6VhOG1+4BZaSVsoCouk3ZbG/9sK5GsHpZIoURDA==
-----END RSA PRIVATE KEY-----
From browser(1.0.1f)
string(916) "-----BEGIN PRIVATE KEY-----
MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALdFNQhj4AJXSW6F
25vwFIuN5Uaoo3FD7kHAQXDUSw5IA2j/ZsmjxavVg7y75wna9PDd1zYweyxGAgCZ
Z5E2GN21eP91m/vQpNe+9jXFXxqy2HsLGeIjZ0XNNuFzkUqQXpe+Owzzc/d+MfKT
RbkK9pSWp+jUjlD+RkV/VtxcwxoJAgMBAAECgYEArJc6SDp2PP4iozjgBcxkLMBm
SNKLiSEmATmi5zSlsj9TJtBO5lma0CX1OAnknD1dKnBgOiIR/TG4tQPCqte9NYR6
2T7M9cIBmEnP62VfVGx0karVRvCPqh0CFqZ0hhfY7CMF2ubD0xY880rONA1dhTCm
1UCefWcQUkUunbCe7FkCQQDqHjO9yvucnI16t8T2bf/ju+CkquSLcjL7sL4YXn5q
6Pzonkvs+XdFuPRY+MGFr1rFytZG2nKlC3ZkbYjBnMYDAkEAyGZceyxcLtvGDPW5
FZPYHrjtucCsBYzzPeqAiEodWjMp8gikIwNXNLboFDd8SdDTb816Dd2OCe5sj7iL
LsmYAwJBAKqsg+nr7YwZsSZyjDteq7q4/6bsEpr6EOLd0Wdwk9aara1joVRL9UC1
+iRWjLZJxPIG0jlrDUL23UOPerAy+0MCQHorNPv+OiBy6NUjw/asj9eC46IXHIex uuQnHr53eFdx04Ny0yVpNvOzAd65SLLzdMK24E6tn5bcXCBt36PhUCMCQQCJbkVZ
bhH2LFSBOtVeo6B1H5Pws0viow27vH8RiSu7XPw+i7pWE4bX7gFlpJWygKi6Tdls
b/2wrkawelkihREM -----END PRIVATE KEY----- "
Why? Same function, same parametrs, same server. How can it be?
The difference you're seeing is the consequence of the default RSA key format change between PKCS#1 used in the openssl version 0.9.8y and PKCS#8 in openssl version 1.0.1f.
You can use this command to convert the old format key (0.9.8) to the new format (1.0.1):
openssl pkcs8 -topk8 -in prkey.opensslv098y -nocrypt
Or vice versa from 1.0.1 to 0.9.8:
openssl rsa -in prkey.opensslv101f
Related
Environment:
Ubuntu 14.04, PHP 5.5.9, MYSQL 5.6.30
From time to time I get an error
mysqli::real_connect(): SSL operation failed with code 1. OpenSSL
Error message:
error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number
Front/nginx is on one server and mysql is on a different server.
The error is not continuous, it happens randomly and I find those error messages in error log so I cannot really do full debug.
Sample:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$this->objMySqli = mysqli_init();
mysqli_options ($this->objMySqli, MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, true);
$this->objMySqli->ssl_set($this->SslKey, $this->SslCertificate, $this->SslCACertificate, null, null);
$link = $this->objMySqli->real_connect($this->Server, $this->Username, $this->Password, $this->Database, $this->Port);
if (!$link) {
throw new QMySqliDatabaseException("Unable to connect to Database", -1, null);
}
SSL Cipher:
It fails on this line:
$link = $this->objMySqli->real_connect($this->Server, $this->Username, $this->Password, $this->Database, $this->Port);
It is problem with mysql version 5.6.30,
I have updated to 5.6.32 and now this error is not happening anymore.
Upgrading didn't fix my problem, but I did find a new solution.
TLDR; Convert your PKCS#8 format keys to PKCS#1 format keys
openssl rsa -in example.com.server.key.pem -out example.com.server.key.pkcs1.pem
I ran into these bugs:
MySQL Bug 71271
MySQL Bug 64870
Essentially, if your private key is in PKCS#8 format instead of PKCS#1 format, MySQL will not "find" the private key.
A lot of Stack Overflow answers say rename the header and footer to include RSA in the header and footer like so:
From (PKCS#8 format)
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
To (PKCS#1 format)
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
However, this does not change the private key data between the header and footer. When using my PKCS#8 format key with the modified header and footer, no error occured at MySQL startup, but when I tried to connect with mysqli I got
error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number
By converting my private keys to PKCS#1 format, the keys worked and I could connect fine:
openssl rsa -in example.com.server.key.pem -out example.com.server.key.pkcs1.pem
Note that newer OpenSSL versions, at least 1.0.2j (what I was using) output PKCS#8 keys when using
openssl req -config "openssl.cnf" \
-keyout "private/example.com.server.key.pem" -new -sha256 \
-days 3652 -nodes -out "csr/example.com.server.csr.pem"
but using different options may output PKCS#1 keys (possibly -newkey rsa:2048, I haven't tested). Which would explain why only some people are experiencing this when using openssl generated private keys.
This problem occurred form me in MySQL 5.6.17 and 5.7.14, so it seems like the bugs are not fixed.
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 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"];
?>
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.