Php openssl_pkey_export doesn't work - php

I'm trying to build a blockchain and for that, I need to generate a public and a private key and use the sign function and the verify function, from research I found that those functions were in the OpenSSL function, but I can't figure how this one works , I got the following code that I copied from the PHP doc :
// Create the keypair
$res=openssl_pkey_new();
// Get private key
openssl_pkey_export($res, $privkey);
// Get public key
$pubkey=openssl_pkey_get_details($res);
$pubkey=$pubkey["key"];
$data = 'plaintext data goes here';
openssl_sign("hello",$signature,$privKey);
$test=openssl_verify("hello",$signature,$pubKey,"sha256");
echo $test;
and this gives me: openssl_pkey_export(): cannot get key from parameter 1.
ps: i'm on windows

Related

How to export the private key from a Salesforce Self Signed cert using PHP or openssl?

I created a Self-Signed cert by following this article I set the private key as exportable but there isn't an export link within the salesforce app (that I can see) so I'm guessing you have to export from the certificate itself. I'm using the PHP openssl x509 functions but i can't get it to work. I keep getting openssl_sign(): supplied key param cannot be coerced into a private key... when I run this code:
...
$private_key = openssl_get_privatekey(file_get_contents(env('SALESFORCE_CERT_FILE')));
$s = "";
openssl_sign($header . '.' . $payload, $s, $private_key, "SHA256");
...
I figured it out. In salesforce they do have an "export" button that says "Export to Keystore". I was unfamiliar with this so I didn't think to use it. I was looking for export private key or something like that. Turns out you can just following the answer to this stack exchange question to get your private key.

How to create the access token using app user id in Box-API?

I'm trying to create the access token using box app user id. I have use the following code to create the box app user
curl https://api.box.com/2.0/users \
-H "Authorization: Bearer <TOKEN>" \
-d '{"name": "Ned Stark", "is_platform_access_only": true}' \
-X POST
Then it is give the following result
{"type":"user","id":"2199107004","name":"Ned Stark","login":"AppUser_399382_9BNZHI03nJ#boxdevedition.com","created_at":"2017-08-03T00:58:04-07:00"
Is it possible to generate the access token using box app user id.?
Edited
I have generate the Public key in BOX API. Then I have file which is having Public key and Private key detail like as bellow,
{
"boxAppSettings": {
"clientID": <Client ID>,
"clientSecret": <clientsecret>,
"appAuth": {
"publicKeyID": <publickeyid>,
"privateKey": "-----BEGIN ENCRYPTED PRIVATE KEY-----\Key heresn-----END ENCRYPTED PRIVATE KEY-----\n",
"passphrase": <phrase>
}
},
"enterpriseID": <enterpriseId>
}
Then I have generate header and payload, which is as follow
$header = ["typ"=> "JWT", "alg"=>"RS256","kid"=> <public key id>];
$payload = [
"iss"=> "<client id>",
"sub"=> "<APP USER ID>",
"box_sub_type"=> "user",
"aud"=>"https://api.box.com/oauth2/token",
"jti"=>"<I don't know what is this>",
"exp"=>1428699385
];
$header = base64_encode(json_encode($header));
$payload = base64_encode(json_encode($payload));
After this I got stuck how to implement the private and public key here. Actually I'm having the JSON file which is downloaded from BOX API.
And I can't understand what is the JTI? How to add the public key and|or private key JSON file in this? How to do it?
And I have generate the private key manually as per document, as follow
openssl genrsa -aes256 -out private_key.pem 2048
Then I gave the password as "12345". And generate public key as follow,
openssl rsa -pubout -in private_key.pem -out public_key.pem
Then I added the public key in BOX-API and I made a code as follow,
$data = file_get_contents('private_key.pem');
$result = openssl_pkey_get_private($data,"12345");
print_r($result);
It gives the following result
Resource id #4
These is not looking like encrypted data. And how to implement private and public when calling box api in php.?
I won't recommend you to implement this yourself since there are already a couple of libraries implementing this protocol. However I split my answer into 2 parts the first part explains how to use an open source package to solve your problem, the second part helps you out if you want to do private keys signing.
Using a package
There are a couple of php packages that support JWT signing, at the moment of writing the one that is used most is lcobucci/jwt, but there are also other implementations found here:
https://packagist.org/search/?q=jwt
You can use composer to install it. Since version 4.0 is not documented right now I suggest you install 3.2 and have a look at the README file of that version.
You can require this in your project using: composer require lcobucci/jwt:^3.2
Your code sample suggests you need RSA256, the library has an example for that:
<?php
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Keychain; // just to make our life simpler
use Lcobucci\JWT\Signer\Rsa\Sha256; // you can use Lcobucci\JWT\Signer\Ecdsa\Sha256 if you're using ECDSA keys
$signer = new Sha256();
$keychain = new Keychain();
$token = (new Builder())
->setIssuer('http://example.com') // Configures the issuer (iss claim)
->setAudience('http://example.org') // Configures the audience (aud claim)
->setId('4f1g23a12aa', true) // Configures the id (jti claim), replicating as a header item
->setIssuedAt(time()) // Configures the time that the token was issue (iat claim)
->setNotBefore(time() + 60) // Configures the time that the token can be used (nbf claim)
->setExpiration(time() + 3600) // Configures the expiration time of the token (nbf claim)
->set('uid', 1) // Configures a new claim, called "uid"
->sign($signer, $keychain->getPrivateKey('file://{path to your private key}')) // creates a signature using your private key
->getToken(); // Retrieves the generated token
Signing and verifying
When using public and private keys you always have to be sure to keep your private key safe. You can however easily publish your public key to the world without compromising security.
Signing is done using the private key, since you don't want people to be able to fake your signature, signing with the public part would make it possible for everyone to do it. This also means that the verify step always uses the public key, because everyone should be able to do it.
Doing it in PHP
The code example you provided simply loads a private key, but does not do any action with it. In order to sign you will need to use openssl_sign with your variable. Resource #xx simply means a reference to something external in php.
<?php
// Data to sign
$payload = 'TEST';
// Generate a new key, load with: openssl_pkey_get_private
$privateKey = openssl_pkey_new(array('private_key_bits' => 512)); // NOT SECURE BUT FAST
// Extract public part from private key
$details = openssl_pkey_get_details($privateKey);
// Use openssl_pkey_get_public to load from file
$publicKey = $details['key'];
// Generated by openssl_sign
$signature = null;
// Sign with private key
openssl_sign($payload, $signature, $privateKey, OPENSSL_ALGO_SHA256);
// Use base64 because the signature contains binairy data
echo 'Signed data: '.base64_encode($signature).PHP_EOL;
// Use publicKey to verify signature
$valid = openssl_verify($payload, $signature, $publicKey, OPENSSL_ALGO_SHA256);
echo 'Signature is '.($valid ? 'Valid' : 'Invalid').PHP_EOL;
What else
If you still want to implement the complete protocol I suggest you have another look at the package. And as already suggested by the comments the complete specification:
https://www.rfc-editor.org/rfc/rfc7519.txt
Last hint: JWT uses some different characters for base64 than php so be sure to handle that correctly.

OpenSSL only generates public key [duplicate]

Okay, well, this is my first time working with encryption on a project. I am using my hosting provider for SSL, but I also want to encrypt portions of the database that are sensitive. For this, I was told to use OpenSSL. I am testing it on my localhost (WAMP), and have installed OpenSSL and turned on the PHP and Apache SSL mods. Okay, so i've been following tutorials and, using several suggested methods, have been able to generate the public key and store it as a file. For some reason, I can't seem to generate the private key. I will post two versions of code that i've tried:
// generate private key
$privateKey = openssl_pkey_new(array(
'private_key_bits' => 1024,
'private_key_type' => OPENSSL_KEYTYPE_RSA,
));
// write private key to file
openssl_pkey_export_to_file($privateKey, 'private.key');
// generate public key from private key
$publicKey = openssl_pkey_get_details($privateKey);
// write public key to file
file_put_contents('public.key', $publicKey['key']);
// clear key
echo $privateKey;
?>
This generates a public.key file, but provides me the warnings "openssl_pkey_export_to_file(): cannot get key from parameter 1:" and " openssl_pkey_get_details() expects parameter 1 to be resource, boolean."
I also tried an alternative method:
$config = array(
"config" => "E:/wamp/bin/apache/apache2.2.22/conf/openssl.cnf",
"digest_alg" => "sha512",
"private_key_bits" => 1024,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
);
// Create the private and public key
$res = openssl_pkey_new($config);
// Extract the private key from $res to $privKey
openssl_pkey_export($res, $privKey, NULL);
echo "Private Key: ".$privKey;
// Extract the public key from $res to $pubKey
$pubKey = openssl_pkey_get_details($res);
$pubKey = $pubKey["key"];
echo "Public Key: ".$pubKey;
$data = 'plaintext data goes here';
echo "Data: ".$data;
// Encrypt the data to $encrypted using the public key
openssl_public_encrypt($data, $encrypted, $pubKey);
echo "Encrypted: ".$encrypted;
// Decrypt the data using the private key and store the results in $decrypted
openssl_private_decrypt($encrypted, $decrypted, $privKey);
echo "Decrypted: ".$decrypted;
This was supposed to echo everything, unfortunately my result was a blank private key, a fine public key, plaintext, and encrypted text, and an error when trying to decrypt: "openssl_private_decrypt(): key parameter is not a valid private key"
Clearly, i'm having a problem with private key creation. I've searched the internet thoroughly and haven't been able to fix it, even though I've implemented simple code that seems to work for everyone else.
Thanks in advance,
Elie Zeitouni
I know that it has been a while and you may have already solved it but I think that my answer can be helpful for other people who faced the same problem (Like I did).
So if you take a look at the openssl_pkey_export() documentation you can find that it takes four different parameters. If we take a look at your second implementation we can see that you have only provided three.
openssl_pkey_export($res, $privKey, NULL);
This would be just as fine if only your server have the right environment variables for OPENSSL_CONF. Linking to the openssl.cnf file, which as quoted in the README-SSL.txt file that is downloaded with XAMPP is required to make use of CSR and key generation functions from PHP.
To use the CSR and key generation functions from PHP, you will need to install an openssl.cnf file. We have included a sample file that can be used for this purpose in this folder alongside this readme file.
For this reason just as you did for the openssl_pkey_new($config); you must create a associative array containing the config => '/path/to/openssl.cnf'. Just like this:
openssl_pkey_export($res, $privKey, NULL, $config);
I would like to also add that the path of openssl.cnf in my case is inside:
C:\xampp\php\extras\openssl\openssl.cnf
Inside here you will also be able to find a README-SSL.txt file which give a good explaination of how to configure OPENSSL.
Hope it helps. :)
I think you might have an easier time with phpseclib, a pure PHP RSA implementation. The following example will create a 1024-bit RSA private / public key:
<?php
include('Crypt/RSA.php');
$rsa = new Crypt_RSA();
extract($rsa->createKey());
echo $privatekey . '<br/>' . $publickey;
?>
Banged around my head with getting this to work on windows10 with xampp php 5.5. Finally figured tabone's answer above was in the right direction EXCEPT path format needed to be forward slashed!
C:/xampp/php/extras/openssl/openssl.cnf
Hope this helps someone.
I Had the same problem.
And it is Windows problem's !!!
It won't happen on unix base systems.
And, If like me you use Windows only for Development, you use PuTTYGen to generate a key, and use it, static, in dev enviroment !
OR
OpenSSL not working on Windows, errors 0x02001003 0x2006D080 0x0E064002
use : openssl_pkey_export_to_file($result, 'privkey.pem', null, $config);
This worked for wampp/php 7.0.4
$privateKey = openssl_pkey_new(array(
'config' => 'C:/wamp/bin/php/php7.0.4/extras/ssl/openssl.cnf',
'private_key_bits' => 1024,
'private_key_type' => OPENSSL_KEYTYPE_RSA,
));
// write private key to file
openssl_pkey_export_to_file($privateKey, 'private.key');
// generate public key from private key
$publicKey = openssl_pkey_get_details($privateKey);
// write public key to file
file_put_contents('public.key', $publicKey['key']);
// clear key
echo $privateKey;

PHP curl send public key

I'm trying to connect to an API and have been told that I need to send our public key to match the public key I sent them via email.
I'm setting the public key by using:
curl_setopt($c, CURLOPT_SSLCERT, [path to file]);
I'm getting this error:
unable to set private key file: [path to file] type PEM
Am I missing something? I know that typically key-based encryption requires a private and public key but they specifically wanted me to send them the public key via email and specifically want me sending them the public key via code.
Turns out that I also needed CURLOPT_SSLKEY which is the private key. Apparently cURL requires both, but sends only the public key?

OpenSSL won't create private keys?

Okay, well, this is my first time working with encryption on a project. I am using my hosting provider for SSL, but I also want to encrypt portions of the database that are sensitive. For this, I was told to use OpenSSL. I am testing it on my localhost (WAMP), and have installed OpenSSL and turned on the PHP and Apache SSL mods. Okay, so i've been following tutorials and, using several suggested methods, have been able to generate the public key and store it as a file. For some reason, I can't seem to generate the private key. I will post two versions of code that i've tried:
// generate private key
$privateKey = openssl_pkey_new(array(
'private_key_bits' => 1024,
'private_key_type' => OPENSSL_KEYTYPE_RSA,
));
// write private key to file
openssl_pkey_export_to_file($privateKey, 'private.key');
// generate public key from private key
$publicKey = openssl_pkey_get_details($privateKey);
// write public key to file
file_put_contents('public.key', $publicKey['key']);
// clear key
echo $privateKey;
?>
This generates a public.key file, but provides me the warnings "openssl_pkey_export_to_file(): cannot get key from parameter 1:" and " openssl_pkey_get_details() expects parameter 1 to be resource, boolean."
I also tried an alternative method:
$config = array(
"config" => "E:/wamp/bin/apache/apache2.2.22/conf/openssl.cnf",
"digest_alg" => "sha512",
"private_key_bits" => 1024,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
);
// Create the private and public key
$res = openssl_pkey_new($config);
// Extract the private key from $res to $privKey
openssl_pkey_export($res, $privKey, NULL);
echo "Private Key: ".$privKey;
// Extract the public key from $res to $pubKey
$pubKey = openssl_pkey_get_details($res);
$pubKey = $pubKey["key"];
echo "Public Key: ".$pubKey;
$data = 'plaintext data goes here';
echo "Data: ".$data;
// Encrypt the data to $encrypted using the public key
openssl_public_encrypt($data, $encrypted, $pubKey);
echo "Encrypted: ".$encrypted;
// Decrypt the data using the private key and store the results in $decrypted
openssl_private_decrypt($encrypted, $decrypted, $privKey);
echo "Decrypted: ".$decrypted;
This was supposed to echo everything, unfortunately my result was a blank private key, a fine public key, plaintext, and encrypted text, and an error when trying to decrypt: "openssl_private_decrypt(): key parameter is not a valid private key"
Clearly, i'm having a problem with private key creation. I've searched the internet thoroughly and haven't been able to fix it, even though I've implemented simple code that seems to work for everyone else.
Thanks in advance,
Elie Zeitouni
I know that it has been a while and you may have already solved it but I think that my answer can be helpful for other people who faced the same problem (Like I did).
So if you take a look at the openssl_pkey_export() documentation you can find that it takes four different parameters. If we take a look at your second implementation we can see that you have only provided three.
openssl_pkey_export($res, $privKey, NULL);
This would be just as fine if only your server have the right environment variables for OPENSSL_CONF. Linking to the openssl.cnf file, which as quoted in the README-SSL.txt file that is downloaded with XAMPP is required to make use of CSR and key generation functions from PHP.
To use the CSR and key generation functions from PHP, you will need to install an openssl.cnf file. We have included a sample file that can be used for this purpose in this folder alongside this readme file.
For this reason just as you did for the openssl_pkey_new($config); you must create a associative array containing the config => '/path/to/openssl.cnf'. Just like this:
openssl_pkey_export($res, $privKey, NULL, $config);
I would like to also add that the path of openssl.cnf in my case is inside:
C:\xampp\php\extras\openssl\openssl.cnf
Inside here you will also be able to find a README-SSL.txt file which give a good explaination of how to configure OPENSSL.
Hope it helps. :)
I think you might have an easier time with phpseclib, a pure PHP RSA implementation. The following example will create a 1024-bit RSA private / public key:
<?php
include('Crypt/RSA.php');
$rsa = new Crypt_RSA();
extract($rsa->createKey());
echo $privatekey . '<br/>' . $publickey;
?>
Banged around my head with getting this to work on windows10 with xampp php 5.5. Finally figured tabone's answer above was in the right direction EXCEPT path format needed to be forward slashed!
C:/xampp/php/extras/openssl/openssl.cnf
Hope this helps someone.
I Had the same problem.
And it is Windows problem's !!!
It won't happen on unix base systems.
And, If like me you use Windows only for Development, you use PuTTYGen to generate a key, and use it, static, in dev enviroment !
OR
OpenSSL not working on Windows, errors 0x02001003 0x2006D080 0x0E064002
use : openssl_pkey_export_to_file($result, 'privkey.pem', null, $config);
This worked for wampp/php 7.0.4
$privateKey = openssl_pkey_new(array(
'config' => 'C:/wamp/bin/php/php7.0.4/extras/ssl/openssl.cnf',
'private_key_bits' => 1024,
'private_key_type' => OPENSSL_KEYTYPE_RSA,
));
// write private key to file
openssl_pkey_export_to_file($privateKey, 'private.key');
// generate public key from private key
$publicKey = openssl_pkey_get_details($privateKey);
// write public key to file
file_put_contents('public.key', $publicKey['key']);
// clear key
echo $privateKey;

Categories