Как расшифровать C++ OpenSSL ChaCha20 из nodeJS?C++

Программы на C++. Форум разработчиков
Anonymous
 Как расшифровать C++ OpenSSL ChaCha20 из nodeJS?

Сообщение Anonymous »

Я пытаюсь расшифровать данные, зашифрованные с помощью C++ OpenSSL ChaCha20 из Node.js, но стандартный криптомодуль Node.js не поддерживает напрямую ChaCha20 без Poly1305.
Я пробовал использовать библиотеку JsChaCha20, это не помогло, но расшифрованные данные неверны, функция decrypt возвращает это: 'bAۄ����@��'
Я пытаюсь понять, проблема ли это в моем коде, в библиотеке JsChaCha20 или даже в несоответствии реализации OpenSSL и библиотеки.

Код: Выделить всё

// https://github.com/thesimj/js-chacha20/blob/master/src/jschacha20.js
import crypto     from 'crypto'
import JSChaCha20 from './jschacha20.js'

function decrypt(data, password)
{
if (!data.length)
return false

// Generate a salt from the password
const pwhash = crypto.createHash('sha256').update(password).digest()
const salt   = Buffer.from(pwhash)

const NONCE_SIZE = 12
const KEY_SIZE   = 32

// Derive key from password
const key = crypto.createHash('sha256').update(password).digest()

// Derive nonce
const context = Buffer.concat([Buffer.from(password), salt])
const hash    = crypto.createHash('sha256').update(context).digest()
const nonce   = hash.slice(0, NONCE_SIZE)

// Log values for comparison
console.log('\nkey\n', key.toString('base64'))
console.log('\nnonce\n', nonce.toString('base64'))
console.log('\nsalt\n', salt.toString('base64'))
console.log('\ncontext\n', context.toString('base64'))

try
{
const decipher = new JSChaCha20(key, nonce)
let decrypted  = decipher.decrypt(Buffer.from(data))
decrypted      = Buffer.from(decrypted).toString('utf8')
return decrypted
}
catch (error)
{
console.error(error.message)
return false
}
}

let encrypted   = "b1OnS61xyC/D0Dc="
encrypted       = Buffer.from(encrypted, 'base64')
const decrypted = decrypt(encrypted, "password")
Моя реализация C++ OpenSSL ChaCha20:

Код: Выделить всё

#include 
#include 
#include 
#include 

bool encrypt(std::string& data, std::string& password)
{
if (data.empty())
return false;

// Generate a salt from the password
unsigned char pwhash[SHA256_DIGEST_LENGTH];
SHA256(reinterpret_cast(password.data()), password.size(), pwhash);
std::vector salt(pwhash, pwhash + 32);

constexpr size_t NONCE_SIZE = 12;
constexpr size_t KEY_SIZE = 32;

// Derive key from password
unsigned char key[KEY_SIZE];
SHA256(reinterpret_cast(password.data()), password.size(), key);

// Derive nonce
std::vector context;
context.reserve(password.size() + salt.size());
context.insert(context.end(), password.begin(), password.end());
context.insert(context.end(), salt.begin(), salt.end());

unsigned char hash[SHA256_DIGEST_LENGTH];
SHA256(context.data(), context.size(), hash);
std::vector nonce(hash, hash + NONCE_SIZE);

// Encrypt with derived nonce
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
if (!ctx) return false;
if (EVP_EncryptInit_ex(ctx, EVP_chacha20(), nullptr, key, nonce.data()) != 1) {
EVP_CIPHER_CTX_free(ctx);
return false;
}

std::vector ciphertext(data.size(), 0);
int ciphertextLen;
if (EVP_EncryptUpdate(ctx, reinterpret_cast(ciphertext.data()), &ciphertextLen,
reinterpret_cast(data.data()), data.size()) != 1) {
EVP_CIPHER_CTX_free(ctx);
return false;
}
EVP_CIPHER_CTX_free(ctx);
ciphertext.resize(ciphertextLen);

// Print key, nonce, salt, and context in base64
auto toBase64 = [](const unsigned char* data, size_t len) -> std::string {
BIO* b64 = BIO_new(BIO_f_base64());
BIO* bio = BIO_new(BIO_s_mem());
bio = BIO_push(b64, bio);
BIO_write(bio, data, len);
BIO_flush(bio);
BUF_MEM* bufferPtr;
BIO_get_mem_ptr(bio, &bufferPtr);
std::string result(bufferPtr->data, bufferPtr->length - 1);  // Exclude the null terminator
BIO_free_all(bio);
return result;
};

std::cout 

Подробнее здесь: [url]https://stackoverflow.com/questions/79045149/how-to-decrypt-c-openssl-chacha20-from-nodejs[/url]

Вернуться в «C++»