Help needed to understand PHP Libsodium and how to export keys.

I'm trying to implement a solution using PHP and Libsodium.

I'm working off of this example:

// On Alice's computer:

$alice_box_kp = sodium_crypto_box_keypair();
$alice_sign_kp = sodium_crypto_sign_keypair();

    // Split the key for the crypto_box API for ease of use
    $alice_box_secretkey = sodium_crypto_box_secretkey($alice_box_kp);
    $alice_box_publickey = sodium_crypto_box_publickey($alice_box_kp);
    
    // Split the key for the crypto_sign API for ease of use
    $alice_sign_secretkey = sodium_crypto_sign_secretkey($alice_sign_kp);
    $alice_sign_publickey = sodium_crypto_sign_publickey($alice_sign_kp);

// On Bob's computer:

$bob_box_kp = sodium_crypto_box_keypair();
$bob_sign_kp = sodium_crypto_sign_keypair();

    // Split the key for the crypto_box API for ease of use
    $bob_box_secretkey = sodium_crypto_box_secretkey($bob_box_kp);
    $bob_box_publickey = sodium_crypto_box_publickey($bob_box_kp);
    
    // Split the key for the crypto_sign API for ease of use
    $bob_sign_secretkey = sodium_crypto_sign_secretkey($bob_sign_kp);
    $bob_sign_publickey = sodium_crypto_sign_publickey($bob_sign_kp);

// Optionally, you can reassemble a keypair string from a secret key and 
// public key pair:

$keypair = sodium_crypto_box_keypair_from_secretkey_and_publickey(
    $alice_box_secretkey,
    $alice_box_publickey
);

Open in new window


Basically, stuck on the part where I need to export the public keys so I can share them with another user.

Server A has a private and public key generating in code, but I don't know how to export it.
Server B has a private and public key generating in code, but I don't know how to export it.

Once exported, I will need to know how to import the keys so I can decrypt the messages.

I used to use open_ssl library which was straightforward, but my company desire to use the libsodium libraries now and I can't seem to find any functions to export the keys.
LVL 13
Andrew DerseIT ManagerAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

David FavorLinux/LXD/WordPress/Hosting SavantCommented:
That's a really good question.

I just brought up a PHP-7.2 LXD container this morning to start testing WordPress.

My guess is, follow the https://wiki.php.net/rfc/libsodium example.

Using the variable names from the example, save...

$key into a private key file for future use.

$message into a public key file for future use.

Also http://blog.siphos.be/2015/08/switching-openssh-to-ed25519-keys suggests you may be able to generate your keys via ssh-keygen.
Andrew DerseIT ManagerAuthor Commented:
Yeah, I'm stuck at this exact location...

Using the variable names from the example, save...

$key into a private key file for future use.

$message into a public key file for future use.

I can get everything to display on the pages...but how do I put stuff into a private key file? Do you know where I might be able to find documentation on that?
David FavorLinux/LXD/WordPress/Hosting SavantCommented:
I think... because PHP-7.2 has only been out a few days...

I'd likely export/save these files using a naming convention of $name-sodium.key + $name-sodium.pub in some directory... maybe...

/etc/apache/sodium/...

Since your private + public keys are just strings, you'd just pick a naming convention, using directories readable/writable by your PHP FPM process owner, which will likely be same as /etc/apache2 owner... if you're using Debian/Ubuntu...

When you determine a convention you'll be using, be sure + publish what you do in this thread.

You're breaking new ground, we'll all have to traverse shortly.

If you publish your notes, you may save someone a massive amount of headaches/time when they have to navigate the same terrain.
OWASP: Forgery and Phishing

Learn the techniques to avoid forgery and phishing attacks and the types of attacks an application or network may face.

Andrew DerseIT ManagerAuthor Commented:
Sounds good, I'll keep you posted!
David FavorLinux/LXD/WordPress/Hosting SavantCommented:
Thanks!
Andrew DerseIT ManagerAuthor Commented:
Here's the solution I was able to come up with.

Since the generated keys are in binary, I just exported everything to a .txt file. Then you can follow the example with no problems. :)

Here's the code.

generate_keys.php // RUN THIS FROM THE CLI ON THE SERVER
<?php

/*
 * Based off of this example from Paragonie
 * https://paragonie.com/book/pecl-libsodium/read/05-publickey-crypto.md
 *
 * Author: Andrew Derse
 * Date: 12/22/2017
 *
 * !! Run this file from the CLI in order to generate the keys. !!
 *
 */


// User A
$alice_box_kp = sodium_crypto_box_keypair();

// Split the key for the crypto_box API for ease of use
$alice_box_secretkey = sodium_crypto_box_secretkey($alice_box_kp);
$alice_box_publickey = sodium_crypto_box_publickey($alice_box_kp);

// A - private key
$a_pri_file = 'keys/a_pri.txt';
$h = fopen($a_pri_file, 'w');
fwrite($h, $alice_box_secretkey);
fclose($h);

// A - public key
$a_pub_file = 'keys/a_pub.txt';
$h = fopen($a_pub_file, 'w');
fwrite($h, $alice_box_publickey);
fclose($h);

// User B
$bob_box_kp = sodium_crypto_box_keypair();

// Split the key for the crypto_box API for ease of use
$bob_box_secretkey = sodium_crypto_box_secretkey($bob_box_kp);
$bob_box_publickey = sodium_crypto_box_publickey($bob_box_kp);

// B - private key
$b_pri_file = 'keys/b_pri.txt';
$h = fopen($b_pri_file, 'w');
fwrite($h, $bob_box_secretkey);
fclose($h);

// B - public key
$b_pub_file = 'keys/b_pub.txt';
$h = fopen($b_pub_file, 'w');
fwrite($h, $bob_box_publickey);

Open in new window


crypt.php // RUN THIS FROM THE BROWSER
<?php

/*
 * Based off of this example from Paragonie
 * https://paragonie.com/book/pecl-libsodium/read/05-publickey-crypto.md
 *
 * Author: Andrew Derse
 * Date: 12/22/2017
 *
 * !! Run this file from the browser. !!
 *
 */

// Get and extract A - private key
$a_pri_file = 'keys/a_pri.txt';
$h = fopen($a_pri_file, 'r');
$a_pri_key = fread($h,filesize($a_pri_file));
fclose($h);

// Get and extract B - public key
$b_pub_file = 'keys/b_pub.txt';
$h = fopen($b_pub_file, 'r');
$b_pub_key = fread($h,filesize($b_pub_file));
fclose($h);

// Encrypt basic message.
$message = 'Hi, this is Alice';
$a_to_b_kp = sodium_crypto_box_keypair_from_secretkey_and_publickey(
	$a_pri_key,
	$b_pub_key
);

$nonce = random_bytes(SODIUM_CRYPTO_BOX_NONCEBYTES);
$ciphertext = sodium_crypto_box(
	$message,
	$nonce,
	$a_to_b_kp
);

// Get and extract A - public key
$a_pub_file = 'keys/a_pub.txt';
$h = fopen($a_pub_file, 'r');
$a_pub_key = fread($h,filesize($a_pub_file));
fclose($h);

// Get and extract B - private key
$b_pri_file = 'keys/b_pri.txt';
$h = fopen($b_pri_file, 'r');
$b_pri_key = fread($h,filesize($b_pri_file));
fclose($h);

// Make key pair for BA
$b_to_a_kp = sodium_crypto_box_keypair_from_secretkey_and_publickey(
	$b_pri_key,
	$a_pub_key
);


$plaintext = sodium_crypto_box_open(
	$ciphertext,
	$nonce,
	$b_to_a_kp
);

if ($plaintext === false) {
	throw new Exception("Malformed message or invalid MAC");
}
echo 'Cipher text: ' . $ciphertext . '<br />';
echo 'Plain text: ' . $plaintext;

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Andrew DerseIT ManagerAuthor Commented:
Solution provided in text above.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.