0

I am creating a Password Manager and I wanted to create a JavaScript function to encrypt/decrypt data in the client-side, then I will be saving the only the encrypted data in MySQL Server. To encrypt/decrypt I am using Crypto-JS. This is what I have created so far:

HTML <head>:

<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>

Code:

function EncryptData(data, password){
    var iterations = 10000;
    var salt = CryptoJS.lib.WordArray.random(128 / 8).toString();
    try {
        var password_hash = CryptoJS.SHA512(password + salt);
        var key = CryptoJS.PBKDF2(password_hash, salt, { keySize: 512 / 32, iterations: iterations }).toString();
        var ciphertext = CryptoJS.AES.encrypt(data, key, { mode: CryptoJS.mode.CFB, padding: CryptoJS.pad.Pkcs7 });
        var params = iterations + ':' + salt + ':' + ciphertext;
        var encoded = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(params));
        console.log(encoded);
    } catch(error) {
        console.log("Unable to encrypt data.");
    }
}

function DecryptData(data, password){ var decoded = CryptoJS.enc.Base64.parse(data).toString(CryptoJS.enc.Utf8); var iterations = decoded.split(':')[0]; var salt = decoded.split(':')[1]; var ciphertext = decoded.split(':')[2]; try { var password_hash = CryptoJS.SHA512(password + salt); var key = CryptoJS.PBKDF2(password_hash, salt, { keySize: 512 / 32, iterations: iterations }).toString(); var cleartext = CryptoJS.AES.decrypt(ciphertext, key, { mode: CryptoJS.mode.CFB, padding: CryptoJS.pad.Pkcs7 }).toString(CryptoJS.enc.Utf8); console.log(cleartext); } catch(error) { console.log("Unable to decrypt data."); } }

Encrypt data

EncryptData("This is a simple demo", "abc123");

Decrypt data

DecryptData("MTAwMDA6MDg3NjNiZjEwNDM1YzhkZTJkMGU2NjM5M2I1M2YxNDc6VTJGc2RHVmtYMStxZWZZSmJ2eTJHak85cTdxOS9kK2dYaCt6UHRBcjJXMEt3bE1uakNaaTY5QmVmKzA3Y1lkaw==", "abc123");

The code works fine. I would like to read comments to know if this is secure enough (of course abc123 should be replaced by a mega secure password).

Manuel
  • 9
  • 2
  • This library was useful some years ago, because there was no myna alternatives at that time. Now all major browsers support Web Crypto API/SubtleCrypto. I'd recommend you to use this API, not libraries that implement it from scratch. Usually, browser developers have more resources to properly test their functionality. That's why you can expect it is more reliable than solutions developed by a small community behind particular library. This is crucial for cryptographic functionality. – mentallurg May 19 '23 at 20:46

1 Answers1

2

This is not secure for several reasons.

The crypto-js library you're using is almost two years old and seems to have been abandoned completely. The issues keep piling up, and there doesn't seem to be anyone to take care of them. I would stay away from dead software.

Cryptography in the browser also has conceptual issues and a large attack surface. First, there's no clear separation between “client-side” and “server-side”, because all the code which the client runs is dynamically provided by the server. If the server made a small change to completely break the encryption, the client likely wouldn't notice that. An attacker can also use cross-site scripting or similar attacks to mess with the client-side encryption procedure (e. g. grab the plaintext password before it's hashed).

Last but not least, coming up with your own ad-hoc security solution is always error-prone. A small mistake anywhere in the code (not necessarily in the cryptography itself) can expose all plaintext passwords and render the entire project useless.

The proper solution here is to use a well-tested, well-maintained password manager like KeePassXC, possibly together with browser plugins.

Ja1024
  • 5,769
  • 14
  • 21
  • The big part of this answer is not helpful. – mentallurg May 19 '23 at 20:08
  • "The issues keep piling up..." - I'd suggest to check what kind of issues these are. The most of them are usability issues, not security issues. In first 50 issues I see only 1 that (if confirmed) is relevant for security, it is issue #442.
  • – mentallurg May 19 '23 at 20:11
  • "Cryptography in the browser also has conceptual issues" - No. This is not true.
  • – mentallurg May 19 '23 at 20:12
  • "large attack surface" - No. May be you mean risks related to leak of secrets. But this does not say anything about the cryptographic strength. This is determined by the algorithms (which are standard, like AES) and the quality of implementation (unless you have examples of incorrect implementation you should not do such strong statements; check all issues; if you find any weaknesses, lest us know).
  • – mentallurg May 19 '23 at 20:17