Reputation: 27
Is it possible to password protect a file without the use of .htaccess, php, or localhost. Maybe with some type of encryption or an other method.
Upvotes: 1
Views: 3045
Reputation: 92467
Yes you can encrypt any message using only JS without backend and without store password in your JS code. I will describe simple theoretical approach without technical details:
Encryption:
Decryption:
As you can see, you don't need to store password anywhere in this approach.
Upvotes: 0
Reputation: 5769
Inspired by @Kaiido I developed a JavaScript Bookmarklet. So, add it as a new bookmark in your browser and click on it to encrypt the current page. You will be asked to insert a password and choose a location where to save the encrypted HTML page.
javascript:(function (doc) {
var password = prompt('Enter a password to encrypt this page'),
js = doc.createElement('script');
js.onload = function () {
/* Get current page HTML and use a dirty workaround to convert relative paths to full URLs */
var page = doc.documentElement.cloneNode(true);
for (var attr of ['src', 'href']) {
page.querySelectorAll('[' + attr + ']').forEach(function (node) {
node[attr] = node[attr];
});
}
/* All the magic belongs to openpgpjs.org */
openpgp.encrypt({
message: openpgp.message.fromText(page.outerHTML),
passwords: [password]
}).then(function (ciphertext) {
var link = doc.createElement('a'),
html = [
'<!DOCTYPE html>',
'<head>',
' <meta charset="utf-8" />',
'</head>',
'<body>',
' <textarea id="encryptedMessage" style="display:none">' + ciphertext.data + '</textarea>',
' <script src="' + js.src + '"></script>',
' <script>',
' var field=document.getElementById("encryptedMessage");',
' openpgp.message.readArmored(field.value).then(function(message){',
' var decrypter=openpgp.decrypt({message:message,passwords:[prompt("Enter the password to decrypt this page")]});',
' decrypter.then(function(plaintext){document.documentElement.innerHTML=plaintext.data});',
' decrypter.catch(function(e){alert(String(e))});',
' });',
' </script>',
'</body>'
].join('\n');
doc.body.appendChild(link);
link.download = 'protected.html';
link.href = 'data:text/html;,' + encodeURIComponent(html);
link.click();
doc.body.removeChild(link);
});
};
/* This will fail if Content Security Policy prohibits embedded scripts */
js.src = 'https://cdnjs.cloudflare.com/ajax/libs/openpgp/4.3.0/compat/openpgp.min.js';
doc.body.appendChild(js);
})(document);
An example of encrypted page can be found here: http://fiddle.jshell.net/yjLwq0mx/show/light/
Upvotes: 0
Reputation: 136755
Yes, you can achieve pretty decent front-side encryption, thanks to the SubtleCrypto API.
There is even a js port of openpgp.
So yes, you could ultimately encode whatever data you wish as pgp message for instance, then require a password to decrypt it and use it.
If you need to encrypt your message:
(async function() {
const cleartext = 'alert("an useless message")';
const msg = openpgp.message.fromText(cleartext);
const ciphertext = await openpgp.encrypt({
message: msg,
passwords: ["mypassword"],
armor: true
});
// you'd be better saving as a text file though,
// ecnoding and new line characters matter
console.log(ciphertext.data);
})()
.catch(console.error);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/openpgp.min.js"></script>
And then to decrypt it:
(async function() {
const password = prompt('enter password ("mypassword")');
// one of the results of previous snippet
const encrypted = `-----BEGIN PGP MESSAGE-----
Version: OpenPGP.js v4.3.0
Comment: https://openpgpjs.org
wy4ECQMI61wIzRzOswzg/j6zhPvasbu97nt+XeD23m3UNnc8J3SqAGiogvn8
zqKD0lMB49BViJ8gQ7E/6If6vaCv9NBojjVgS9P2E7mROtZrbz5Z150ohcKV
kDncF//Io6sb/5L/5AcLXBxCJzhQKIYwtIdHu9paWGpEto1z5EzOGzpZgg==
=hMhM
-----END PGP MESSAGE-----`;
const decrypted = await openpgp.decrypt({
message: await openpgp.message.readArmored(encrypted),
passwords: [password]
})
const cleartext = decrypted.data;
console.log(cleartext);
new Function(cleartext)();
})()
.catch(console.error);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/openpgp.min.js"></script>
Upvotes: 4
Reputation: 373
No. Well, not anything that offers anything remotely secure. You could hide a password in the javascript, maybe encoded as base64 and then compare the value of an input field to the stored base64 code, but anyone that knows anything about "view source" or javascript would easily be able to circumvent this.
Password authentication and other sensitive information must be processed on the server side, where users can't get to it!
Upvotes: 1