Skip to content

Instantly share code, notes, and snippets.

@habeeb-salami
Forked from therightstuff/_end-to-end-enc.js.md
Created September 22, 2020 00:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save habeeb-salami/90249fad39c232ae32c6913a1959b6f2 to your computer and use it in GitHub Desktop.
Save habeeb-salami/90249fad39c232ae32c6913a1959b6f2 to your computer and use it in GitHub Desktop.
Javascript / Node.js end-to-end encryption
<html>
<head>
<!-- The following package is required https://www.npmjs.com/package/simple-free-encryption-tool -->
<script src="js/windowSfet.js"></script>
<script language="javascript">
// SECURITY_LEVEL is the encryption key size in bits
let SECURITY_LEVEL = 2048;
// internet explorer can't handle 2048 bit key generation in a reasonable amount of time, so we use 1024 bit.
// this will have minimal impact as the credentials are secured using an externally transmitted verification
// code and cracking the client->server comms won't (usually) compromise server->client comms
// if client->server comms being compromised is a serious problem, then simply force the user to wait
if ((window.navigator.userAgent.indexOf('MSIE') > 0) ||
(window.navigator.userAgent.indexOf('Trident/7') > 0) ||
(window.navigator.userAgent.indexOf('Edge/') > 0)) {
SECURITY_LEVEL = 1024;
}
// RSA keys used to secure the session
let keys = {
client: {},
server: {}
};
// generate the client's keys for the session
function generateSessionKeys {
console.log('generating ' + SECURITY_LEVEL + '-bit key pair...');
keys.client = sfet.rsa.generateKeysSync(SECURITY_LEVEL);
console.log('Keys Generated in ' + keys.client.time);
}
// load existing session keys from storage or generate new keys
function loadSessionKeys() {
// ensure html5 storage available
if (typeof (Storage) !== "undefined") {
if (sessionStorage.RSAKeys) {
keys = JSON.parse(sessionStorage.RSAKeys);
console.log('client keys loaded from session storage');
} else {
generateSessionKeys();
sessionStorage.RSAKeys = JSON.stringify(keys);
console.log('session keys saved to storage');
}
} else {
console.log('Sorry! No Web Storage support..');
// it's possible to continue with new keys generated per page,
// but then you'll have to repeat the key exchange with a new code
}
}
function packMessageData(data) {
data = JSON.stringify(data);
let packedData = {};
// generate aes secret
let aesSecret = sfet.utils.randomstring.generate();
try {
// add RSA-encrypted aes secret to output
packedData.key = sfet.rsa.encrypt(keys.server.public, aesSecret);
// add encrypted data to output
packedData.encrypted = sfet.aes.encrypt(aesSecret, data);
return packedData;
} catch (dataEncryptionException) {
console.log('failed to pack message: ' + dataEncryptionException.message);
return {};
}
}
function unpackMessageData(data) {
var secret = sfet.rsa.decrypt(keys.client.private, data.key);
var message = JSON.parse(sfet.aes.decrypt(secret, data.encrypted));
}
</script>
</head>
<body>
</body>
</html>
var sfet = require('simple-free-encryption-tool');
var SECURITY_LEVEL = 2048;
// generate shared secret for session authentication
var generateSessionSecret = function () {
// number between 4 and 8
var secretLength = Math.floor((Math.random() * 5) + 4);
// session secret must not include ambiguous characters like O/0, 1/l
var secret = sfet.utils.randomstring.generate({
length: secretLength,
readable: true
});
return secret;
};
function pack(data) {
data = JSON.stringify(data);
var packedData = {};
// generate aes key
let aesSecret = sfet.utils.randomstring.generate();
// add encrypted aes key to output
packedData.key = sfet.rsa.encrypt(clientPublicKey, aesSecret);
// add encrypted data to output
packedData.encrypted = sfet.aes.encrypt(aesSecret, data);
return packedData;
}
function unpack(data) {
var aesSecret = sfet.rsa.decrypt(serverPrivateKey, data.key);
return sfet.aes.decrypt(aesSecret, data.encrypted);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment