@tera-insights/tc-form-utilities
v0.1.1
Published
tiCrypt Form Encryption/Decryption Utilities
Downloads
5
Readme
tiFormEncrypt
This is an encryption/decryption library that can be used together with the tiForms mechanism in tiCrypt to allow secure form submission. Once encrypted, the form data can only be decrypted using the form private key.
Overview
The main usage scenario for tiFormEncrypt is the folliwing:
- The tiCrypt client creates a
publicKey
-privateKey
key pair, aformID
and oneapiID
for each independent web server. TheprivateKey
is encrypted and kept secret (i.e. it is available only through tiCrypt frontend interface). - The web server stores internally (e.g. in config files) the
publicKey
,formID
andapiID
. OnlypublicKey
is made available to the web client (e.g it is injected in the javascript code as a global constant). - The web client is provided the
publicKey
. It harvests data (e.g. form data), and encrypts the data using Eliptic Curve Diffie-Helman (ECDH) with a randomly generated provate key and the provide publicKey. The public part of the generated key and the encrypted payload are handed over to the web server. - The web server gets the data from the web client and adds
formID
andapiID
and submits it to the tiCrypt backent. - Latter, through the tiCrypt client, the
privateKey
is recovered and the form data accessed and decrypted (via ECDH).
Client Interface
First, the encryption library has to be included in the html sources:
<script type="text/javascript" src="dist/tiForms.js"></script>
The form publicKey
is made available by the web server, for example by injecting
<script>
var formPublicKey = "kjsaldfjjsfljas|asdfasdfasdfasdf";
</script>
in the main html code.
Assuming the web server accepts POSTS on /submit
route and using jquery
(raw AJAX or other frameworks can be used as well), the client code to submit any data object can be:
function submitMyData(obj){
var objAsString = JSON.stringify(obj);
tiForms.ready( function(){
var encryptor = tiForms.MakeEncryptor(formPublicKey);
// make sure the encryptor is ready
encryptor.ready( function(){
encryptor.encryptStringCB(objAsString,
function(data){ // success
$.post('/submit', data);
}, function(err){ // post failed
console.error(err);
}
);
});
});
}
Notice the use of tiForms.ready()
. Without it, the shimming for Edge and Safari will
not work properly. ready()
can be called as many times as desired; it will detect the
capabilities only once.
Alternatively, the above code can be written more elegantly using promises:
// submits the encrypted form and return a promise that indicates success or failure
function submitMyData(obj){
tiForms.ready( function(){
var encryptor = tiForms.MakeEncryptor(formPublicKey);
// make sure the encryptor is ready
return encryptor.ready().then( function(){
return encryptor.encryptString(JSON.stringify(obj))
.then( function(data){
return $.post('/submit', data);
})
});
});
}
$('#myButton').click( function(){
submitMyData( $('myForm').serializeArray() )
.then( function(){
$('#successmsg').show();
}, function(){
$('#failmsg').show();
})
});
Note The AES encryption key and the private key of the Elliptic Curve generated by the tiForms.js
library is non-extractable. Under no circusmstance should you change the tiForms.js
library and make the keys extractable since that would break the security model. The AES decryption key can be recovered by the tiCrypt client from the public part of the Elliptic Curve key and the form private key.
Web server Interface
The web server has minimal requirements:
- It must implement authentication (if desired)
- It must implement a POST route on which the data gets submitted from the client. For example
/submit
- It must be able to manipulate the client submited data and add the
formID
andapiID
fields;
The object received from the client has the form:
{
"publicKey": "akljdsflkjasdlkfjasdjf|lalaksdfkjsldfjalsj",
"payload": "ldaksjflkasjjkjklajsldkfjlkasjdflkjasdlkfjlaskdjflkasjdflkjasldfkjas"
}
The object is send to the tiCrypt server must look like:
{
"formID": "kjlkjlakjlkdfjalskajd",
"appID": "asdefkaldsfalsdfkadfsf",
"publicKey": "akljdsflkjasdlkfjasdjf|lalaksdfkjsldfjalsj",
"payload": "ldaksjflkasjjkjklajsldkfjlkasjdflkjasdlkfjlaskdjflkasjdflkjasldfkjas"
}
The data is send as a POST on the route /forms/
.
The web server can submit the data to the tiCrypt backend withtout any session or credentials except correct formID
and matching appID
.
Note 1 It is absolutely critical that the web server does not store or logs the content received from the client.
Note 2 The formID
and the appID
should not be made available to the client and shoudl be guarded with the same care that the SSL/TLS certificate is handled.
Development
Installation
Make sure the following packages are installed globaly
webpack
karma
Then npm install
to get the remaining packages.
Instructions
- To run tests, do
karma test
- To start example server do
cd examples/formSubmit; node server.js
then navigate tolocalhost:3000
orlocalhost:3000/bulk
- To rebuild library do
webpack
- To rebuild server do
webpack --config server.wp.config.js