I have a PHP application which can communicate with other PHP applications.
Theses apps exchange encrypted data.
A central app knows all public keys of other apps.
And other apps only know the public key of the central app.
The data are encrypted thanks to the openssl_seal PHP method.
And there are decrypted thanks to the openssl_open PHP method.
I use the "AES256" cypher method and generate an "iv" element.
In PHP no problem at all, everything is for the best in the best of all possible worlds …
But, now, I would like to do the same with an Ionic app (based on cordova and Angular 5).
I tried to use JSEncrypt and CryptoJS, but PHP dos not explain how openssl_seal works and I have some trouble to export my PHP code into Javascript one …
function encrypt($message)
{
$envKeys = [];
$encMessage = '';
$pubKey = "-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----
";
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('AES256'));
if (openssl_seal($message, $encMessage, $envKeys, [$pubKey], 'AES256', $iv) === false) {
throw new Exception("Erreur lors du cryptage du message !");
}
return [base64_encode($encMessage), base64_encode($envKeys[0]), base64_encode($iv)];
}
function decrypt($messageCrypte, $key, $iv)
{
$privateKey = "-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
";
$message = '';
openssl_open(base64_decode($messageCrypte), $message, base64_decode($key), $privateKey, 'AES256', base64_decode($iv));
return $message;
}
$crypted = encrypt('Test');
$embed = "<script>var encrypted = '$crypted[0]'; var envelope = '$crypted[1]'; var iv = '$crypted[2]'; </script>";
<html>
<head>
<script type="text/javascript" src="crypto-js.js"></script>
<script type="text/javascript" src="jsencrypt.js"></script>
<?php echo $embed; ?>
<script>
var private_key = `-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
`;
var crypt = new JSEncrypt();
crypt.setPrivateKey(private_key);
var theKey = CryptoJS.enc.Utf8.parse(crypt.decrypt(envelope));
console.log('The key', theKey);
console.log('ciphertext', CryptoJS.enc.Base64.parse(encrypted));
var decrypted = CryptoJS.AES.decrypt(
{ciphertext: CryptoJS.enc.Base64.parse(encrypted)},
theKey,
{iv: CryptoJS.enc.Base64.parse(iv)}
);
console.log('Decrypted', decrypted.toString());
</script>
</head>
<body>
</body>
</html>
I don't have the original message "Test" … Only empty string … I would like to be able to make an openssl_seal (like the PHP one) method in JS and an openssl_open (like the PHP one) using CryptoJS and JSEncrypt. I think it's possible, maybe someone already did that …
Edit
If someone is interested by this problem, I maybe found a lead : http://geekswithblogs.net/Strenium/archive/2013/01/27/converting-phprsquos-ldquoopenssl_sealrdquo-and-ldquoopenssl_openrdquo-into-.net.aspx
It is for .NET but it's a start …