kopia lustrzana https://github.com/robinmoisson/staticrypt
add salt and key derivation, close #113
rodzic
591f697a46
commit
ea2da5be81
|
@ -16,7 +16,7 @@ It basically encrypts your page and puts everything with a user-friendly way to
|
||||||
|
|
||||||
AES-256 is state of the art but brute-force/dictionary attacks would be trivial to do at a really fast pace: **use a long, unusual passphrase**.
|
AES-256 is state of the art but brute-force/dictionary attacks would be trivial to do at a really fast pace: **use a long, unusual passphrase**.
|
||||||
|
|
||||||
The concept is simple but I am not a cryptographer, feel free to contribute or report any thought to the GitHub project!
|
The concept is simple but I am not a cryptographer, feel free to contribute or report any thought to the GitHub project! (Though be warned it might take me a long time to get to it - I apologize in advance)
|
||||||
|
|
||||||
## CLI
|
## CLI
|
||||||
|
|
||||||
|
|
32
cli/index.js
32
cli/index.js
|
@ -60,9 +60,37 @@ try{
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Salt and encrypt a msg with a password.
|
||||||
|
* Inspired by https://github.com/adonespitogo
|
||||||
|
*/
|
||||||
|
var keySize = 256;
|
||||||
|
var iterations = 1000;
|
||||||
|
function encrypt (msg, password) {
|
||||||
|
var salt = CryptoJS.lib.WordArray.random(128/8);
|
||||||
|
|
||||||
|
var key = CryptoJS.PBKDF2(password, salt, {
|
||||||
|
keySize: keySize/32,
|
||||||
|
iterations: iterations
|
||||||
|
});
|
||||||
|
|
||||||
|
var iv = CryptoJS.lib.WordArray.random(128/8);
|
||||||
|
|
||||||
|
var encrypted = CryptoJS.AES.encrypt(msg, key, {
|
||||||
|
iv: iv,
|
||||||
|
padding: CryptoJS.pad.Pkcs7,
|
||||||
|
mode: CryptoJS.mode.CBC
|
||||||
|
});
|
||||||
|
|
||||||
|
// salt, iv will be hex 32 in length
|
||||||
|
// append them to the ciphertext for use in decryption
|
||||||
|
var encryptedMsg = salt.toString()+ iv.toString() + encrypted.toString();
|
||||||
|
return encryptedMsg;
|
||||||
|
}
|
||||||
|
|
||||||
// encrypt input
|
// encrypt input
|
||||||
var encrypted = CryptoJS.AES.encrypt(contents, password);
|
var encrypted = encrypt(contents, password);
|
||||||
var hmac = CryptoJS.HmacSHA256(encrypted.toString(), CryptoJS.SHA256(password).toString()).toString();
|
var hmac = CryptoJS.HmacSHA256(encrypted, CryptoJS.SHA256(password).toString()).toString();
|
||||||
var encryptedMessage = hmac + encrypted;
|
var encryptedMessage = hmac + encrypted;
|
||||||
|
|
||||||
// create crypto-js tag (embedded or not)
|
// create crypto-js tag (embedded or not)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "staticrypt",
|
"name": "staticrypt",
|
||||||
"version": "1.2.0",
|
"version": "1.3.2",
|
||||||
"description": "Based on the [crypto-js](https://github.com/brix/crypto-js) library, StatiCrypt uses AES-256 to encrypt your input with your passphrase and put it in a HTML file with a password prompt that can decrypted in-browser (client side).",
|
"description": "Based on the [crypto-js](https://github.com/brix/crypto-js) library, StatiCrypt uses AES-256 to encrypt your input with your passphrase and put it in a HTML file with a password prompt that can decrypted in-browser (client side).",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
|
@ -143,6 +143,30 @@
|
||||||
{crypto_tag}
|
{crypto_tag}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* Decrypt a salted msg using a password.
|
||||||
|
* Inspired by https://github.com/adonespitogo
|
||||||
|
*/
|
||||||
|
var keySize = 256;
|
||||||
|
var iterations = 1000;
|
||||||
|
function decrypt (encryptedMsg, pass) {
|
||||||
|
var salt = CryptoJS.enc.Hex.parse(encryptedMsg.substr(0, 32));
|
||||||
|
var iv = CryptoJS.enc.Hex.parse(encryptedMsg.substr(32, 32))
|
||||||
|
var encrypted = encryptedMsg.substring(64);
|
||||||
|
|
||||||
|
var key = CryptoJS.PBKDF2(pass, salt, {
|
||||||
|
keySize: keySize/32,
|
||||||
|
iterations: iterations
|
||||||
|
});
|
||||||
|
|
||||||
|
var decrypted = CryptoJS.AES.decrypt(encrypted, key, {
|
||||||
|
iv: iv,
|
||||||
|
padding: CryptoJS.pad.Pkcs7,
|
||||||
|
mode: CryptoJS.mode.CBC
|
||||||
|
}).toString(CryptoJS.enc.Utf8);
|
||||||
|
return decrypted;
|
||||||
|
}
|
||||||
|
|
||||||
document.getElementById('staticrypt-form').addEventListener('submit', function(e) {
|
document.getElementById('staticrypt-form').addEventListener('submit', function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
|
@ -157,7 +181,7 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var plainHTML = CryptoJS.AES.decrypt(encryptedHTML, passphrase).toString(CryptoJS.enc.Utf8);
|
var plainHTML = decrypt(encryptedHTML, passphrase);
|
||||||
|
|
||||||
document.write(plainHTML);
|
document.write(plainHTML);
|
||||||
document.close();
|
document.close();
|
||||||
|
|
34
example.html
34
example.html
|
@ -118,7 +118,8 @@
|
||||||
<div class="staticrypt-form">
|
<div class="staticrypt-form">
|
||||||
<div class="staticrypt-instructions">
|
<div class="staticrypt-instructions">
|
||||||
<p class="staticrypt-title">Protected Page</p>
|
<p class="staticrypt-title">Protected Page</p>
|
||||||
<p>Enter "test" to unlock the page</p>
|
<p><p>Enter "test" to unlock the page</p>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr class="staticrypt-hr">
|
<hr class="staticrypt-hr">
|
||||||
|
@ -140,14 +141,39 @@
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
||||||
<script src="kryptojs-3.1.9-1-lib.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.min.js" integrity="sha384-lp4k1VRKPU9eBnPePjnJ9M2RF3i7PC30gXs70+elCVfgwLwx1tv5+ctxdtwxqZa7" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrypt a salted msg using a password.
|
||||||
|
* Inspired by https://github.com/adonespitogo
|
||||||
|
*/
|
||||||
|
var keySize = 256;
|
||||||
|
var iterations = 1000;
|
||||||
|
function decrypt (encryptedMsg, pass) {
|
||||||
|
var salt = CryptoJS.enc.Hex.parse(encryptedMsg.substr(0, 32));
|
||||||
|
var iv = CryptoJS.enc.Hex.parse(encryptedMsg.substr(32, 32))
|
||||||
|
var encrypted = encryptedMsg.substring(64);
|
||||||
|
|
||||||
|
var key = CryptoJS.PBKDF2(pass, salt, {
|
||||||
|
keySize: keySize/32,
|
||||||
|
iterations: iterations
|
||||||
|
});
|
||||||
|
|
||||||
|
var decrypted = CryptoJS.AES.decrypt(encrypted, key, {
|
||||||
|
iv: iv,
|
||||||
|
padding: CryptoJS.pad.Pkcs7,
|
||||||
|
mode: CryptoJS.mode.CBC
|
||||||
|
}).toString(CryptoJS.enc.Utf8);
|
||||||
|
return decrypted;
|
||||||
|
}
|
||||||
|
|
||||||
document.getElementById('staticrypt-form').addEventListener('submit', function(e) {
|
document.getElementById('staticrypt-form').addEventListener('submit', function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
var passphrase = document.getElementById('staticrypt-password').value,
|
var passphrase = document.getElementById('staticrypt-password').value,
|
||||||
encryptedMsg = '46000e585e625a99008c89c628710dc4b798c864fa810ae0458bc6b49a703f90U2FsdGVkX1+g3FXrsAI5EjFDMufRodFX1zR4khDb1ua1hT7e2Wjt3k9089USzxeyquHa8Yk5VZ7e6PoJ68Y9QibpQUedY7HMJC9k2WNw+ojPdk0xzPxSBWY7pDX+ZoLUzEztNzxsnPhQITmN8WfRdz6+3ortQmGRUn1qAXznRviSh5t7HzwlkRFEeNqjMJCB/Mjj+OnWpXZeNLo6nAdEag==',
|
encryptedMsg = '1c5350b7566531a9aa06d5c186b58de688287a5f64c1439fadab7c5f8ffd3c676a558d9e37e7c0c4b8df03fbb0149c292c02cff335c90cc2ccc7e02fcda394247bvtjq4PeULRWa0f/TewJBGyaHeltmS3NITxoMwMpHJoe4E4AXjJqHcFjHY+1H6u1IIxjQlP4/WRDUu6U+QG+eHIfOgwE4sz+9CkrHFSG8HX2p0NpEs7HYls8rZEk1SKcMrtlzuSwKBV60jIketViNVFHmnbPJYmK0FKVQcFh19EO1dtuvAK8M3CMVOPUIYh',
|
||||||
encryptedHMAC = encryptedMsg.substring(0, 64),
|
encryptedHMAC = encryptedMsg.substring(0, 64),
|
||||||
encryptedHTML = encryptedMsg.substring(64),
|
encryptedHTML = encryptedMsg.substring(64),
|
||||||
decryptedHMAC = CryptoJS.HmacSHA256(encryptedHTML, CryptoJS.SHA256(passphrase).toString()).toString();
|
decryptedHMAC = CryptoJS.HmacSHA256(encryptedHTML, CryptoJS.SHA256(passphrase).toString()).toString();
|
||||||
|
@ -157,7 +183,7 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var plainHTML = CryptoJS.AES.decrypt(encryptedHTML, passphrase).toString(CryptoJS.enc.Utf8);
|
var plainHTML = decrypt(encryptedHTML, passphrase);
|
||||||
|
|
||||||
document.write(plainHTML);
|
document.write(plainHTML);
|
||||||
document.close();
|
document.close();
|
||||||
|
|
32
index.html
32
index.html
|
@ -198,6 +198,34 @@ Filename changed to circumvent adblockers that mistake it for a crypto miner (se
|
||||||
request.send();
|
request.send();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Salt and encrypt a msg with a password.
|
||||||
|
* Inspired by https://github.com/adonespitogo
|
||||||
|
*/
|
||||||
|
var keySize = 256;
|
||||||
|
var iterations = 1000;
|
||||||
|
function encrypt (msg, password) {
|
||||||
|
var salt = CryptoJS.lib.WordArray.random(128/8);
|
||||||
|
|
||||||
|
var key = CryptoJS.PBKDF2(password, salt, {
|
||||||
|
keySize: keySize/32,
|
||||||
|
iterations: iterations
|
||||||
|
});
|
||||||
|
|
||||||
|
var iv = CryptoJS.lib.WordArray.random(128/8);
|
||||||
|
|
||||||
|
var encrypted = CryptoJS.AES.encrypt(msg, key, {
|
||||||
|
iv: iv,
|
||||||
|
padding: CryptoJS.pad.Pkcs7,
|
||||||
|
mode: CryptoJS.mode.CBC
|
||||||
|
});
|
||||||
|
|
||||||
|
// salt, iv will be hex 32 in length
|
||||||
|
// append them to the ciphertext for use in decryption
|
||||||
|
var encryptedMsg = salt.toString()+ iv.toString() + encrypted.toString();
|
||||||
|
return encryptedMsg;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle form submission.
|
* Handle form submission.
|
||||||
*/
|
*/
|
||||||
|
@ -211,8 +239,8 @@ Filename changed to circumvent adblockers that mistake it for a crypto miner (se
|
||||||
var unencrypted = document.getElementById('unencrypted_html').value;
|
var unencrypted = document.getElementById('unencrypted_html').value;
|
||||||
var passphrase = document.getElementById('passphrase').value;
|
var passphrase = document.getElementById('passphrase').value;
|
||||||
|
|
||||||
var encrypted = CryptoJS.AES.encrypt(unencrypted, passphrase);
|
var encrypted = encrypt(unencrypted, passphrase);
|
||||||
var hmac = CryptoJS.HmacSHA256(encrypted.toString(), CryptoJS.SHA256(passphrase).toString()).toString();
|
var hmac = CryptoJS.HmacSHA256(encrypted, CryptoJS.SHA256(passphrase).toString()).toString();
|
||||||
var encryptedMsg = hmac + encrypted;
|
var encryptedMsg = hmac + encrypted;
|
||||||
|
|
||||||
var pageTitle = document.getElementById('title').value.trim();
|
var pageTitle = document.getElementById('title').value.trim();
|
||||||
|
|
|
@ -143,6 +143,31 @@
|
||||||
{crypto_tag}
|
{crypto_tag}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrypt a salted msg using a password.
|
||||||
|
* Inspired by https://github.com/adonespitogo
|
||||||
|
*/
|
||||||
|
var keySize = 256;
|
||||||
|
var iterations = 1000;
|
||||||
|
function decrypt (encryptedMsg, pass) {
|
||||||
|
var salt = CryptoJS.enc.Hex.parse(encryptedMsg.substr(0, 32));
|
||||||
|
var iv = CryptoJS.enc.Hex.parse(encryptedMsg.substr(32, 32))
|
||||||
|
var encrypted = encryptedMsg.substring(64);
|
||||||
|
|
||||||
|
var key = CryptoJS.PBKDF2(pass, salt, {
|
||||||
|
keySize: keySize/32,
|
||||||
|
iterations: iterations
|
||||||
|
});
|
||||||
|
|
||||||
|
var decrypted = CryptoJS.AES.decrypt(encrypted, key, {
|
||||||
|
iv: iv,
|
||||||
|
padding: CryptoJS.pad.Pkcs7,
|
||||||
|
mode: CryptoJS.mode.CBC
|
||||||
|
}).toString(CryptoJS.enc.Utf8);
|
||||||
|
return decrypted;
|
||||||
|
}
|
||||||
|
|
||||||
document.getElementById('staticrypt-form').addEventListener('submit', function(e) {
|
document.getElementById('staticrypt-form').addEventListener('submit', function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
|
@ -157,7 +182,7 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var plainHTML = CryptoJS.AES.decrypt(encryptedHTML, passphrase).toString(CryptoJS.enc.Utf8);
|
var plainHTML = decrypt(encryptedHTML, passphrase);
|
||||||
|
|
||||||
document.write(plainHTML);
|
document.write(plainHTML);
|
||||||
document.close();
|
document.close();
|
||||||
|
|
Ładowanie…
Reference in New Issue