AES encrypt / decrypt with a passphrase
a-zog opened this issue · 8 comments
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
It's not clear which mechanism it uses. WebCrypto implements AES-CBC, AES-CTR, AES-ECB, and AES-GCM encryption mechanisms.
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"
@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
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)
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
)
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
I see iv
and salt
params in your script. cipherParams.iv.toString()
and cipherParams.salt.toString()