I managed to find a Libsodium js library (JS-NaCl) for front end encryption and has setup my PHP backend for Libsodium encrypt/decrypt also. When I encrypt a JSON object like below
const key = "827ccb0eea8a706c4c34a16891f84e7b";
const nonce = "0123456789abcdefghijvbnm";
var credentials = {
"zip":"265",
"account_number":"10028979739",
"passcode":"1234",
"account_type":"personal",
"request":"login",
"device":"iPhone 11"
};
function encrypt(data){
return sodium.crypto_secretbox(sodium.encode_utf8(data),nonce,key);
};
function decrypt(data){
return sodium.decode_utf8(sodium.crypto_secretbox_open(data, nonce, key));
}
function login(data){
$.ajax({
url:baseURL+"account/account.php",
method:"POST",
contentType:"application/x-www-form-urlencoded",
dataType:"json",
data:"datax="+JSON.stringify(encrypt(credentials)),
beforeSend:()=>{
console.log(credentials);
},success:(response)=>{
console.log(response);
},error:(e)=>{
swal("Connection Error","Failed to connect to the server!","error");
}
});
}
When I fire the login method with it encrypts the JSON object using the encrypt method hence I send something like this:
datax: {"0":191,"1":118,"2":248,"3":134,"4":45,"5":163,"6":3,"7":157,"8":78,"9":73,"10":157,"11":137,"12":178,"13":6,"14":68,"15":91,"16":217,"17":219,"18":50,"19":11,"20":127,"21":177,"22":130,"23":25,"24":209,"25":254,"26":210,"27":44,"28":119,"29":13,"30":144}
at the php backend code I am doing this:
<?php
function decrypt($data){
$key = "e9897cea109576c2f8088c277125d553e4f83afbc0abbb92cfb1f7b776b4fee0";
$nonce = "0123456789abcdefghijvbnm";
return sodium_crypto_secretbox_open($data,$nonce,$key);
}
function encrypt($data){
$data = utf8_encode($data);
$key = "e9897cea109576c2f8088c277125d553e4f83afbc0abbb92cfb1f7b776b4fee0";
$nonce = "0123456789abcdefghijvbnm";
return sodium_crypto_secretbox($data,$nonce,$key);
}
$credentials = $_POST["datax"];
echo decrypt($credentials);
?>
Same Key, Same nonce but it doesn't echo back anything. How to I decrypt this??
The code needs some changes. On the JavaScript side (frontend):
The JavaScript object must be converted into a string.
Besides the data, nonce and key must also be encoded using Utf8. Although the key could also be hexadecimal encoded to a 16 bytes key, in this context it must be Utf8 encoded to a 32 bytes key, because
sodium.crypto_secretbox
expects a 32 bytes key. The expected nonce must be 24 bytes in size.Now the data can be encrypted.
sodium.crypto_secretbox
returns the data asUint8Array
, which must therefore be encoded for transfer into a suitable format, e.g. hexadecimal.The corresponding code is:
On the PHP side (backend):
The hexadecimal string
$encryptedHex
must be decoded.The decoded data are to be decrypted. For this, key and nonce of the encryption must be used. In the posted code a different key is used, which is not possible in the context of
crypto_secretbox
(symmetric encryption), i.e. both sides use the same key. For asymmetric encryption there iscrypto_box
.The result can be decoded into a JavaScript object whose objects can be accessed as usual.
The corresponding code is: