| const crypto = require('crypto'); |
|
|
| function deriveKeyAndIv(password, salt) { |
| const passwordBuf = Buffer.from(password, 'utf8'); |
| let key = Buffer.alloc(0); |
| let iv = Buffer.alloc(0); |
| let lastHash = Buffer.alloc(0); |
|
|
| while (key.length + iv.length < 48) { |
| const hash = crypto.createHash('md5'); |
| hash.update(lastHash); |
| hash.update(passwordBuf); |
| hash.update(salt); |
| lastHash = hash.digest(); |
|
|
| let remaining = lastHash; |
| if (key.length < 32) { |
| const keyToCopy = Math.min(32 - key.length, remaining.length); |
| key = Buffer.concat([key, remaining.slice(0, keyToCopy)]); |
| remaining = remaining.slice(keyToCopy); |
| } |
|
|
| if (remaining.length > 0 && iv.length < 16) { |
| const ivToCopy = Math.min(16 - iv.length, remaining.length); |
| iv = Buffer.concat([iv, remaining.slice(0, ivToCopy)]); |
| } |
| } |
|
|
| return { key, iv }; |
| } |
|
|
| function decrypt(ciphertext, password) { |
| try { |
| const buffer = Buffer.from(ciphertext, 'base64'); |
|
|
| if (buffer.slice(0, 8).toString('utf8') !== 'Salted__') { |
| console.log('Invalid prefix'); |
| return null; |
| } |
|
|
| const salt = buffer.slice(8, 16); |
| const encryptedData = buffer.slice(16); |
|
|
| const keyIv = deriveKeyAndIv(password, salt); |
|
|
| const decipher = crypto.createDecipheriv('aes-256-cbc', keyIv.key, keyIv.iv); |
| let decrypted = decipher.update(encryptedData); |
| decrypted = Buffer.concat([decrypted, decipher.final()]); |
|
|
| return decrypted.toString('utf8'); |
| } catch (e) { |
| console.log('Error:', e.message); |
| return null; |
| } |
| } |
|
|
| const key = "jb%!SZfM%AwwS7JmdM!"; |
| const raw = "U2FsdGVkX19FssG+jADYfE/OYAT3jc+GMe+0/PII+aocWAvEBLte2kN5BTeLZ5+Xk3Tuo/H+6tSqMn49Juxdsg=="; |
|
|
| console.log('Decrypted:', decrypt(raw, key)); |
|
|