Задать вопрос
@NkDev

Как на JavaScript расшифровать строку с помощью ключа?

Помогите пожалуйста переписать следующий код на JavaScript:
<?php

$encrypted_data = 'jPNGTNLtGIBc7Jv2UXj7a3FNQk13eUJ5T3VIUXlOS0ZVOEpnMUpPMnhvQXg5bE5kMGFHejVxaTFnYTA9';
$key = 'qEExPE+jkJxQUt8fSO+XwzXgRGh6kLHy+lWEe6Z8T6s=';

$decoded_data = base64_decode($encrypted_data);
$iv_dec = substr($decoded_data, 0, openssl_cipher_iv_length('AES-256-CBC'));
$encrypted_text = substr($decoded_data, openssl_cipher_iv_length('AES-256-CBC'));

$decrypted = openssl_decrypt($encrypted_text, 'AES-256-CBC', $key, 0, $iv_dec);

echo "Расшифрованная строка: " . $decrypted;


Код на PHP:
https://onlinephp.io/c/f09fe

Вот моя неудачная попытка на JS:
https://playcode.io/2089330
  • Вопрос задан
  • 240 просмотров
Подписаться 1 Средний 1 комментарий
Решения вопроса 1
Lynn
@Lynn
nginx, js, css
С подсказкой от ab1 стало понятно что в PHP ключ (key) не декодируется из base64, а используется как есть. Т.е. из этой строки используются только 32 байта, а остальное просто мусор.

И тогда всё работает.

# key
$ echo qEExPE+jkJxQUt8fSO+XwzXgRGh6kLHy+lWEe6Z8T6s= | xxd -l 32 -ps -c 256
7145457850452b6a6b4a785155743866534f2b58777a5867524768366b4c4879
# iv
$ echo jPNGTNLtGIBc7Jv2UXj7a3FNQk13eUJ5T3VIUXlOS0ZVOEpnMUpPMnhvQXg5bE5kMGFHejVxaTFnYTA9 | base64 -d | xxd -l 16 -ps 
8cf3464cd2ed18805cec9bf65178fb6b
# encrypted text
$ echo jPNGTNLtGIBc7Jv2UXj7a3FNQk13eUJ5T3VIUXlOS0ZVOEpnMUpPMnhvQXg5bE5kMGFHejVxaTFnYTA9 | base64 -d | cut -b 17-
qMBMwyByOuHQyNKFU8Jg1JO2xoAx9lNd0aGz5qi1ga0=
# результат
$ echo qMBMwyByOuHQyNKFU8Jg1JO2xoAx9lNd0aGz5qi1ga0= | openssl AES-256-CBC -d -a -K 7145457850452b6a6b4a785155743866534f2b58777a5867524768366b4c4879 -iv 8CF3464CD2ED18805CEC9BF65178FB6B
/playlist.m3u8+1729705980


Ну и код на JS используя встроенный crypto.subtle:
// Вспомогательные функции
const B = (str) => Uint8Array.from(str, c => c.charCodeAt(0));
const S = (buf) => String.fromCharCode(...new Uint8Array(buf));

// дано
const encryptedData = "jPNGTNLtGIBc7Jv2UXj7a3FNQk13eUJ5T3VIUXlOS0ZVOEpnMUpPMnhvQXg5bE5kMGFHejVxaTFnYTA9";
const key = "qEExPE+jkJxQUt8fSO+XwzXgRGh6kLHy+lWEe6Z8T6s=";

const iv = B(atob(encryptedData).slice(0, 16));
const cryptoKey = await crypto.subtle.importKey(
	'raw',
	// На самом деле используется только 32 байта из key
	B(key.slice(0, 32)),
	'AES-CBC',
	true,
	['encrypt', 'decrypt']
);

const encryptedText = B(atob(atob(encryptedData).slice(16)));

let decrypted = S(await crypto.subtle.decrypt({ name: 'AES-CBC', iv }, cryptoKey, encryptedText));

console.log(decrypted); // /playlist.m3u8+1729705980
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@ab1
Key лучше обрезать до qEExPE+jkJxQUt8fSO+XwzXgRGh6kLHy
и установить padding в None тогда работает в обе стороны
6723ee70cea23058961837.png
6723ee79b6a60901668459.png
Ответ написан
alsolovyev
@alsolovyev
¯\_(ツ)_/¯ Enjoy life, Eat well & Laugh often
Так (для nodejs)?
const crypto = require("crypto");

const encryptedData =
  "jPNGTNLtGIBc7Jv2UXj7a3FNQk13eUJ5T3VIUXlOS0ZVOEpnMUpPMnhvQXg5bE5kMGFHejVxaTFnYTA9";
const key = "qEExPE+jkJxQUt8fSO+XwzXgRGh6kLHy+lWEe6Z8T6s=";

const decodedKey = Buffer.from(key, "base64");
const decodedData = Buffer.from(encryptedData, "base64");
const ivLength = 16; 

const iv = decodedData.slice(0, ivLength);
const encryptedText = decodedData.slice(ivLength);

const decipher = crypto.createDecipheriv("aes-256-cbc", decodedKey, iv);

try {
  let decrypted = decipher.update(encryptedText, null, "utf8");
  decrypted += decipher.final("utf8");
  console.log("Расшифрованная строка:", decrypted);
} catch (error) {
  console.error("Ошибка расшифровки:", error.message);
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы