Using openssl in PHP 5.3 - php

How can I use openssl when accessing data using PHP 5.3?
I hope I can get how to use it. Please give me an example as how to access data using OpenSSL.

Do you want to generate a pair of keys with php?
$NEW_KEY = openssl_pkey_new(array(
'private_key_bits' => 1024,
'private_key_type' => OPENSSL_KEYTYPE_RSA,
));
openssl_pkey_export_to_file($NEW_KEY, 'private.key');
$NEW_KEY_DETAILS = openssl_pkey_get_details($NEW_KEY);
file_put_contents('public.key', $NEW_KEY_DETAILS['key']);
openssl_free_key($NEW_KEY);
Do you already have the keys ?
$public = "-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDfmlc2EgrdhvakQApmLCDOgP0n
NERInBheMh7J/r5aU8PUAIpGXET/8+kOGI1dSYjoux80AuHvkWp1EeHfMwC/SZ9t
6rF4sYqV5Lj9t32ELbh2VNbE/7QEVZnXRi5GdhozBZtS1gJHM2/Q+iToyh5dfTaA
U8bTnLEPMNC1h3qcUQIDAQAB
-----END PUBLIC KEY-----";
$private = "-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDfmlc2EgrdhvakQApmLCDOgP0nNERInBheMh7J/r5aU8PUAIpG
XET/8+kOGI1dSYjoux80AuHvkWp1EeHfMwC/SZ9t6rF4sYqV5Lj9t32ELbh2VNbE
/7QEVZnXRi5GdhozBZtS1gJHM2/Q+iToyh5dfTaAU8bTnLEPMNC1h3qcUQIDAQAB
AoGAcbh6UFqewgnpGKIlZ89bpAsANVckv1T8I7QT6qGvyBrABut7Z8t3oEE5r1yX
UPGcOtkoRniM1h276ex9VtoGr09sUn7duoLiEsp8aip7p7SB3X6XXWJ9K733co6C
dpXotfO0zMnv8l3O9h4pHrrBkmWDBEKbUeuE9Zz7uy6mFAECQQDygylLjzX+2rvm
FYd5ejSaLEeK17AiuT29LNPRHWLu6a0zl923299FCyHLasFgbeuLRCW0LMCs2SKE
Y+cIWMSRAkEA7AnzWjby8j8efjvUwIWh/L5YJyWlSgYKlR0zdgKxxUy9+i1MGRkn
m81NLYza4JLvb8/qjUtvw92Zcppxb7E7wQJAIuQWC+X12c30nLzaOfMIIGpgfKxd
jhFivZX2f66frkn2fmbKIorCy7c3TIH2gn4uFmJenlaV/ghbe/q3oa7L0QJAFP19
ipRAXpKGX6tqbAR2N0emBzUt0btfzYrfPKtYq7b7XfgRQFogT5aeOmLARCBM8qCG
tzHyKnTWZH6ff9M/AQJBAIToUPachXPhDyOpDBcBliRNsowZcw4Yln8CnLqgS9H5
Ya8iBJilFm2UlcXfpUOk9bhBTbgFp+Bv6BZ2Alag7pY=
-----END RSA PRIVATE KEY-----";
if (!$privateKey = openssl_pkey_get_private($private)) die('Loading Private Key failed');
if (!$publicKey = openssl_pkey_get_public($public)) die('Loading Public Key failed');
$encrypted = '';
$decrypted = '';
$plaintext = 'This is just some text to encrypt';
echo '<p>$plaintext = ' . $plaintext . '<p>';
if (!openssl_public_encrypt($plaintext, $encrypted, $publicKey)) die('Failed to encrypt data');
echo '<p>$encrypted = ' . $encrypted . '<p>';
if (!openssl_private_decrypt($encrypted, $decrypted, $privateKey)) die('Failed to decrypt data');
echo '<p>$decrypted = ' . $decrypted . '<p>';
There you go, Enjoy!

Related

How to generate a correct JWT without using Firebase

I am trying to generate a JWT for the DocuSign Embed API and I can't seem to figure out the private/public key part.
When I generate the JWT, the signature part is very short. Pasting it in jwt.io, it turns out both the header and payload are correct, but the signature part is wrong (and way too short when I compare it to what I get when I copy paste my public and rsa private keys.
Here is the relevant code:
$args = [
'envelope_id' => $_GET['envelope_id'],
'ds_return_url' => 'https://www.returnurl.be',
'starting_view' => 'envelope',
'base_path' => 'https://baseurl.be'
];
$args['integration_key'] = 'abc123';
if(isset($_GET['user_id'])) {
$args['user_id'] = $_GET['user_id'];
}
//generate jwt:
$headers = array('alg'=>'RS256','typ'=>'JWT');
$payload = array(
'iss'=>$args['integration_key'],
'sub'=>$args['user_id'],
'aud'=>'account-d.docusign.com', //prod: account.docusign.com
'iat'=>time(),
'exp'=>(time() + 6000),
'scope'=>'signature impersonation'
);
$secret = '-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAj...
-----END RSA PRIVATE KEY-----';
$jwt = generate_jwt($headers, $payload, $secret);
echo $jwt;
function generate_jwt($headers, $payload, $secret = 'secret') {
$headers_encoded = base64url_encode(json_encode($headers));
$payload_encoded = base64url_encode(json_encode($payload));
$signature = hash_hmac('SHA256', "$headers_encoded.$payload_encoded", $secret, true);
$signature_encoded = base64url_encode($signature);
$jwt = "$headers_encoded.$payload_encoded.$signature_encoded";
return $jwt;
}
function base64url_encode($str) {
return rtrim(strtr(base64_encode($str), '+/', '-_'), '=');
}

How signature file data with RSA 2048 & digest sha256?

I am generating a RSA signature in PHP By PHPSECLIB library. According to the instructions, the signature digest must be sha256. Should the digest be set when the key is generated?
I generated Pub/Pri key by blow code: (It should be 2048 and .perm)
$new_key_pair = openssl_pkey_new(array(
"private_key_bits" => 2048,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
));
openssl_pkey_export($new_key_pair, $private_key_pem);
$details = openssl_pkey_get_details($new_key_pair);
$public_key_pem = $details['key'];
file_put_contents('private.pem', $private_key_pem);
file_put_contents('public.pem', $public_key_pem);
I sign data by blow code:
$file_name = "x.json";
$sign_file = "signed/" . $file_name . ".sign";
$data = file_get_contents('files/' . $file_name);
$privatekey = file_get_contents('private.pem');
$rsa = new Crypt_RSA();
$rsa->loadKey($privatekey);
$rsa->setHash('sha256');
$signature = $rsa->sign($data);
file_put_contents($sign_file, $signature);
exit("signed.");
and verify it by
$file_name = "x.json";
$sign_file = "signed/" . $file_name . ".sign";
$publickey = file_get_contents('public.pem');
$data = file_get_contents('files/' . $file_name);
$signature = file_get_contents($sign_file);
$rsa = new Crypt_RSA();
$rsa->setHash('sha256');
$rsa->loadKey($publickey);
$verify = false;
try {
$verify = $rsa->verify($data, $signature);
} catch (Exception $ex) {
$verify = false;
}
echo "verify: " . (($verify) ? "true" : "false") . "<br>";
exit("finished.");
How to set up a digest? Is the signing process correct?

JWT signing with private key on PHP

I have and example how to sign JWT key with private key and then decode it with public one on PHP
$privKey = openssl_pkey_new(array('digest_alg' => 'sha256',
'private_key_bits' => 1024,
'private_key_type' => OPENSSL_KEYTYPE_RSA));
$msg = JWT::encode('abc', $privKey, 'RS256');
$pubKey = openssl_pkey_get_details($privKey);
$pubKey = $pubKey['key'];
$decoded = JWT::decode($msg, $pubKey, array('RS256'));
$this->assertEquals($decoded, 'abc');
but here it generates and then uses generated key on the fly, what if i need to use already generated private and public key? Is it possible/enough to use file_get_contents?
Update
I found openssl_pkey_get_private and openssl_pkey_get_public i'll try to use this code with them.
Solution:
$private = openssl_pkey_get_private('file://key', 'keyphrase');
$token = \Firebase\JWT\JWT::encode('magic', $private, 'RS256');
$public = openssl_pkey_get_public('file://key.pub');
$data = \Firebase\JWT\JWT::decode($token, $public, ['RS256']);

openssl_csr_sign always return false

I use the following script to generate a new signed certificate:
<?php
error_reporting(E_ALL);
// Generate a new private (and public) key pair
$privkey = openssl_pkey_new();
// Generate a certificate signing request
$dn = array(
"countryName" => "US",
"stateOrProvinceName" => "Atlantis",
"localityName" => "NeverEverLand",
"organizationName" => "only me",
"organizationalUnitName" => "blah",
"commonName" => "bleh",
"emailAddress" => "test#test.com"
);
$csr = openssl_csr_new($dn, $privkey);
$cacert = file_get_contents('ca.crt');
echo $cacert . "<BR/>";
echo "<BR/>";
$ca_key = file_get_contents('ca.key');
$cakey = array($ca_key, "mysecretpass");
echo $ca_key . "<BR/>";
echo "<BR/>";
$sscert = openssl_csr_sign($csr, $cacert, $cakey, 365);
var_dump($sscert);
echo "<BR/>";
echo "<BR/>";
openssl_pkey_export($privkey, $pkeyout, "mypassword"); var_dump($pkeyout);
echo "<BR/>";
echo "<BR/>";
openssl_csr_export($csr, $csrout); var_dump($csrout);
echo "<BR/>";
echo "<BR/>";
openssl_x509_export($sscert, $certout); var_dump($certout);
echo "<BR/>";
echo "<BR/>";
while (($e = openssl_error_string()) !== false) {
echo $e . "\n";
}
?>
As you can see in the output it can read ca.crt and ca.key. The pass is also correct (changed in above source).
This is the output of the script:
-----BEGIN CERTIFICATE----- MIIFGDCCAwACCQCO584jngEQdjANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV ... XZ8YaIOkiV4pEiR5 -----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,E616BBF003C1FA9D ... VCPNIOlGzmKUvDn0iMKE0KRmN8o3ip8oy4HKPZmuh4h+qznZdNF/pBTurqcNVN/P -----END RSA PRIVATE KEY-----
bool(false)
string(1834) "-----BEGIN ENCRYPTED PRIVATE KEY----- MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIBX0RFXQVx+ICAggA Bfw= -----END ENCRYPTED PRIVATE KEY----- "
string(1045) "-----BEGIN CERTIFICATE REQUEST----- MIICzDCCAbQCAQAwgYYxCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhBdGxhbnRpczEW zZL71nx/8MgG8hyg63vRRJewb/cCIt1q9A4SwGB9iDe75CbR3ij3jHMftXUfvYhV -----END CERTIFICATE REQUEST----- "
NULL
so the command
openssl_csr_sign($csr, $cacert, $cakey, 365);
returns FALSE, even if all input parameters are valid.
Using CentOS 6.4 / Apache/2.2.15 (CentOS) / mod_ssl/2.2.15

Communicate with APNS from PHP

I would like to communicate with the Apple Push Notification Service from a PHP script.
But I keep getting following error:
Warning: stream_socket_client(): Unable to set private key file
I have a .pem-file which looks like this:
-----BEGIN CERTIFICATE-----
Encrypted String
-----END CERTIFICATE-----
Bag Attributes
friendlyName: ...
localKeyID: ...
Key Attributes: ...
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: ...
DEK-Info: ...
Encrypted String
-----END RSA PRIVATE KEY-----
I am running the PHP script from sudo. It can find my .pem file, because if I remove it, I get a "handshake failure" error instead.
What could be wrong here?
I recently made a script to send remote pushnotifications.
This is how I did it:
$message = "A cool message!";
$deviceid = "";
$count = 0;
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'apns-dev.pem');
$fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);
if (!$fp) {
echo 'Failed to connect ' . $err . $errstr;
} else {
$payloads['aps'] = array('alert' => $message, 'badge' => 1, 'sound' => 'default');
$payload = json_encode($payloads);
$msg = chr(0) . pack('n',32) . pack('H*', $deviceid) . pack('n',strlen($payload)) . $payload;
fwrite($fp, $msg);
$count += 1;
fclose($fp);
}
echo 'Sended: ' . $count;
I got it working. It turns out I exported my private key which I generated for the push notifications instead of the corresponding certificate.

Categories