Creating a private PasteBin with client side encryption.
There have been multiple instance where I quickly wanted to move text between my devices. Most common ways I used to do this was by emailing myself or using google keep. Which is very inefficient and dumb. So I decided to create a personal pastebin clone.
It stores the text in a public database, fully encrypted and decrypts it on the client side using credential stored on client's browser.
Here's some crucial code samples and explanations -
var CryptoJS = require("crypto-js");
import Cookies from 'js-cookie'
var fb = require('./store.js');
if (Cookies.get('key_')) {
var unlocked = true;
var key_ = Cookies.get('key_');
} else if (!Cookies.get('key_')) {
var unlocked = false;
var key_ = null;
alert("¯\_(ツ)_/¯")
}
var inputField_;
export default {
name: 'App',
beforeCreate() {
fb.db.collection("bin").doc("paste")
.onSnapshot(function (doc) {
inputField_ = decrypt(doc.data().field);
this.inputField = decrypt(doc.data().field);
});
},
updated() {
inputField_ = this.inputField
},
data() {
return {
unlocked_: unlocked,
inputField: inputField_,
password: null,
}
},
methods: {
unlock: function (event) {
if (checkKey(this.password)) {
Cookies.set('key_', this.password, {
expires: 365
})
if (this.password) {
this.unlocked_ = true;
this.decrypted = true;
}
}
},
save: function (event) {
// Add a new document in collection "cities"
fb.db.collection("bin").doc("paste").set({
field: encrypt(this.inputField)
})
.then(function () {
console.log("Document successfully written!");
window.navigator.vibrate(200);
})
.catch(function (error) {
console.error("Error writing document: ", error);
});
},
update: function (event) {
this.inputField = inputField_
}
},
computed: {
shit: function () {
alert(inputField_)
return inputField_;
}
}
}
function decrypt(data_) {
if (key_) {
try {
var decrypted = CryptoJS.AES.decrypt(data_, key_);
return decrypted.toString(CryptoJS.enc.Utf8);
} catch (e) {
return data_
console.log(e)
}
} else {
return data_
console.log(e)
}
}
function encrypt(data_) {
if (key_) {
var encrypted = CryptoJS.AES.encrypt(data_, key_);
return encrypted.toString();
} else {
return data_
console.log(e)
}
}
function checkKey(input_) {
var decrypted = CryptoJS.AES.decrypt('U2FsdGVkX19CZxyjXIRZeb3N+ffdvboRFIyQELM1ab0=', input_);
if (decrypted.toString(CryptoJS.enc.Utf8) == "aezakmi") {
return true;
}
}
The app uses vue.js so this is the script part of the app.vue file.
It uses a javascript library - cryptojs to encrypt and decrypt the text on the browser side .
First it checks for the decryption key in the browser cookies and throws out the error for the uses to enter the key. The key is stored in the browser for 1 year.
decrypt() function decrypts the aes256 strings obtained from public database.
encrypt() function encrypts the text to aes256 string using the key from cookies.
the checkKey() function is used to check if the entered key is correct or not by verifying if the entered key decrypts a predetermined text.
They whole thing uses firebase for a database WITHOUT any public rules.
As the data is encrypted to the highest(actually 2nd highest) standard before storing , any 3rd party won't be able to see the data (unless they are able to steal your browser cookies).
This is the final result ! >>
Here's the complete app.vue file for reference. New suggestions are welcome ... Enjoy!