Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AES encrypt / decrypt with a passphrase #54

Open
a-zog opened this issue Sep 7, 2022 · 8 comments
Open

AES encrypt / decrypt with a passphrase #54

a-zog opened this issue Sep 7, 2022 · 8 comments

Comments

@a-zog
Copy link

a-zog commented Sep 7, 2022

Hi,

Great work !

I'm currently switching from CryptoJS and couldn't figure out how to reach this outcome:

var encrypted = CryptoJS.AES.encrypt("Message", "Secret Passphrase");
var decrypted = CryptoJS.AES.decrypt(encrypted, "Secret Passphrase");

Any hint please?

Thank you again for the quality of this repo

@microshine
Copy link
Collaborator

It's not clear which mechanism it uses. WebCrypto implements AES-CBC, AES-CTR, AES-ECB, and AES-GCM encryption mechanisms.

@a-zog
Copy link
Author

a-zog commented Sep 7, 2022

Thank you for the quick response,
I've tried "AES-CBC" on CryptoJS.AES, how would it be implemented on WebCrypto ?
Params seemed confusing, didn't know where to input the "secret Passphrase"

@microshine
Copy link
Collaborator

microshine commented Sep 7, 2022

@a-zog
Looks like crypto-js uses PBKDF2 mechanism for AES key derivation and use it for message encryption/decryption. But it's not clear which params and paddings it uses. If you could share this params I could repeat it using WebCrypto. WebCrypto implements PBKDF2 mechanism too

https://github.com/brix/crypto-js/blob/develop/src/cipher-core.js#L819-L822

@a-zog
Copy link
Author

a-zog commented Sep 7, 2022

Great !

Sure, this is the legacy code I use to AES-CBC encrypt/decrypt :

const passphrase = "secret passphrase"
const valueToEncrypt = "a secret content to encrypt"

const CryptoJSAesJson = {
    stringify: function (cipherParams) {
        const j = {
            ct: cipherParams.ciphertext.toString(CryptoJS.enc.Base64)
        }
        if (cipherParams.iv) j.iv = cipherParams.iv.toString()
        if (cipherParams.salt) j.s = cipherParams.salt.toString()
        return JSON.stringify(j)
    },
    parse: function (jsonStr) {
        const j = JSON.parse(jsonStr)
        let cipherParams = CryptoJS.lib.CipherParams.create({
            ciphertext: CryptoJS.enc.Base64.parse(j.ct)
        })
        if (j.iv) cipherParams.iv = CryptoJS.enc.Hex.parse(j.iv)
        if (j.s) cipherParams.salt = CryptoJS.enc.Hex.parse(j.s)
        return cipherParams
    }
}

const decryptMe = CryptoJS.AES.encrypt(JSON.stringify(valueToEncrypt), passphrase, {
    format: CryptoJSAesJson
}).toString()

CryptoJS.AES.decrypt(decryptMe, passphrase, {
    format: CryptoJSAesJson
}).toString(CryptoJS.enc.Utf8)

@microshine
Copy link
Collaborator

Try something like this

const pbkdf2Key = await crypto.subtle.importKey(
  "raw",
  passwordView, // Password in Uint8Array format
  "PBKDF2",
  false,
  ["deriveKey", "deriveBits"]
);
const aesKey = await crypto.subtle.deriveKey(
  {
    name: "PBKDF2",
    salt: saltView, // Uint8Array
    iterations: 1000,
    hash: { name: "SHA-1" }, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512"
  },
  pbkdf2Key,
  {
    name: "AES-CBC",
    length: 256, // can be  128, 192, or 256
  },
  false,
  ["encrypt", "decrypt"]);

const encryptedMessage = await crypto.subtle.encrypt(
  {
    name: "AES-CBC",
    iv: ivView, // Uint8Array,
  },
  key,
  messageView // Uint8Array
)

@a-zog
Copy link
Author

a-zog commented Sep 10, 2022

Would you please guide me on what to fill the remaining variables? I'm still confused.

This is how I tried to do it:

const passwordView = Uint8Array("secret-key");
const ivView = Uint8Array("secret-key"); // how is this different from password?
const messageView = Uint8Array("my-secret-message");
const saltView = Uint8Array("any random string?");
const key = aesKey ?

Thanks

@microshine
Copy link
Collaborator

I see iv and salt params in your script. cipherParams.iv.toString() and cipherParams.salt.toString()

@trasherdk
Copy link

@a-zog What is in the cipherParams object?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants