• XSS.stack #1 – первый литературный журнал от юзеров форума

Crypto++ AES Decrypt (Помогите)

Zabuza

RAID-массив
Пользователь
Регистрация
02.02.2024
Сообщения
95
Реакции
8
Гарант сделки
5
Помогите понять в чем ошибка, не получается провести декрипт. Приложил рабочий вариант на Python.
Сравнил hex значения всех параметров (salt, iv, key, cipher) - совпадают с тем что в Python.

C++:
#include <iostream>
using std::cerr;
using std::cout;
using std::endl;
using std::string;

#include <vector>
using std::vector;

#include <string>
using std::string;

#include "cryptopp/hex.h"
using CryptoPP::HexDecoder;
using CryptoPP::HexEncoder;

#include "cryptopp/cryptlib.h"
using CryptoPP::AuthenticatedSymmetricCipher;
using CryptoPP::BufferedTransformation;

#include "cryptopp/filters.h"
using CryptoPP::AuthenticatedDecryptionFilter;
using CryptoPP::AuthenticatedEncryptionFilter;
using CryptoPP::Redirector;
using CryptoPP::StringSink;
using CryptoPP::StringSource;

#include "cryptopp/aes.h"
using CryptoPP::AES;

#include "cryptopp/sha.h"
using CryptoPP::SHA256;

#include "cryptopp/pwdbased.h"
using CryptoPP::PKCS5_PBKDF2_HMAC;

#include "cryptopp/gcm.h"
using CryptoPP::GCM;

#include "cryptopp/base64.h"
using CryptoPP::Base64Decoder;

using CryptoPP::byte;

#include "assert.h"

int main(int argc, char *argv[])
{
    // purpose
    byte unused = 0;

    // password
    byte password[] = "Caa5f6daa8#..";
    size_t plen = strlen((const char *)password);

    // salt
    string salt_b64 = "1In+R0F1apmcIOjpkBDRSm3S65OGI3MV02ECZtU2hRY=";
    string salt_temp;
    StringSource ss(salt_b64, true, new Base64Decoder(new StringSink(salt_temp)));
    const byte *salt = (const byte *)salt_temp.data();
    size_t slen = strlen((const char *)salt);

    // key
    byte key[SHA256::DIGESTSIZE];
    PKCS5_PBKDF2_HMAC<SHA256> pbkdf;
    pbkdf.DeriveKey(key, 32, unused, password, plen, salt, slen, 10000);

    // iv
    string iv_b64 = "zbIzYeha9QW4hjw7eAPyYg==";
    string iv_temp;
    StringSource ss2(iv_b64, true, new Base64Decoder(new StringSink(iv_temp)));
    const byte *iv = (const byte *)iv_temp.data();
    size_t ivlen = strlen((const char *)iv);

    // cipher
    string cipher_b64 = "CSESV6gQenLzp+AGy9MypU2lBKjxOiCOXUU+xLYkOb8zYGrNOMw0JkgNWW/PH+184k1jYL2phcinsRd+OWidpSAca9z/w1eVpghvVfFYQ0Z6bp54BAxHHZO4DcWcGSBdpKEmAo4S3pzup6wpSnnupaqyImDQl7pwEg1KmqCQSocnKt3DJzzE/MxOW8byKwqh93bkwwIU9aX+/UJU5e23BU8b1bP2WeFc81huGRDyZS5Mz2OmVJAgfqRdBdXcGByLLp6wq/eDdm04vHw23IJdenU42Pdci8Mt4qdKI9ISfjX4RECE70mPpVtCz032CD/QhZdcwiJM1mwDw/7MOLh2OLwxEBHCdFsdzWfa/qpYHAOaJdt5M3TMB6Mu9Z15KkjBBBfm/WCd26JyhBFywmN6QuDuPsED2Nagz2SFFfyFJssMoAcrtzNC1VYh4q/5vdeNoHGh0lKwkXmmKmOat9GVHq8eDgT5RK3yvPaICbvQNCZ6OEOFrAwvt0asW1PfNgLQoLrbCa5et5B+XzUkzISknItDV9panBLIwOBsb9K3GJJ1BcgwOjHPe2u2XkcXwdRlcGGD3imJZnPEd+m+Kv1VbH2lNcKZ5LXZPYFyszr/+7SDO6PYx+7YJB9ewEpc10AYZ/fMnpOAh6ozDpZwMRwapAbOMhZf";
    string cipher_temp;
    StringSource ss3(cipher_b64, true, new Base64Decoder(new StringSink(cipher_temp)));
    const byte *cipher_full = (const byte *)cipher_temp.data();
    size_t cipher_full_len = strlen((const char *)cipher_full);
    vector<byte> cipher_vector(cipher_full, cipher_full + cipher_full_len);
    vector<byte> cipher_vector_shrinked;
    cipher_vector_shrinked = vector<byte>(cipher_vector.begin(), cipher_vector.end() - 16);
    byte *cipher = &cipher_vector_shrinked[0];
    size_t cipher_len = strlen((const char *)cipher);

    // decrypt
    const int TAG_SIZE = 12;
    GCM<AES>::Decryption d;
    d.SetKeyWithIV(key, sizeof(key), iv, ivlen);

    string rpdata;
    AuthenticatedDecryptionFilter df(d, new StringSink(rpdata), AuthenticatedDecryptionFilter::DEFAULT_FLAGS, TAG_SIZE);
    StringSource ss4(cipher, true, new Redirector(df));

    cout << "Recovered: " << rpdata << endl;

    return 0;
}

Python:
import base64
import hashlib
from Crypto.Cipher import AES

password = "Caa5f6daa8#.."
cipher_b64 = "CSESV6gQenLzp+AGy9MypU2lBKjxOiCOXUU+xLYkOb8zYGrNOMw0JkgNWW/PH+184k1jYL2phcinsRd+OWidpSAca9z/w1eVpghvVfFYQ0Z6bp54BAxHHZO4DcWcGSBdpKEmAo4S3pzup6wpSnnupaqyImDQl7pwEg1KmqCQSocnKt3DJzzE/MxOW8byKwqh93bkwwIU9aX+/UJU5e23BU8b1bP2WeFc81huGRDyZS5Mz2OmVJAgfqRdBdXcGByLLp6wq/eDdm04vHw23IJdenU42Pdci8Mt4qdKI9ISfjX4RECE70mPpVtCz032CD/QhZdcwiJM1mwDw/7MOLh2OLwxEBHCdFsdzWfa/qpYHAOaJdt5M3TMB6Mu9Z15KkjBBBfm/WCd26JyhBFywmN6QuDuPsED2Nagz2SFFfyFJssMoAcrtzNC1VYh4q/5vdeNoHGh0lKwkXmmKmOat9GVHq8eDgT5RK3yvPaICbvQNCZ6OEOFrAwvt0asW1PfNgLQoLrbCa5et5B+XzUkzISknItDV9panBLIwOBsb9K3GJJ1BcgwOjHPe2u2XkcXwdRlcGGD3imJZnPEd+m+Kv1VbH2lNcKZ5LXZPYFyszr/+7SDO6PYx+7YJB9ewEpc10AYZ/fMnpOAh6ozDpZwMRwapAbOMhZf"
iv_b64 = "zbIzYeha9QW4hjw7eAPyYg=="
salt_b64 = "1In+R0F1apmcIOjpkBDRSm3S65OGI3MV02ECZtU2hRY="

encrypted_data = base64.b64decode(cipher_b64)
salt = base64.b64decode(salt_b64)
vector = base64.b64decode(iv_b64)

key = hashlib.pbkdf2_hmac("sha256", password.encode("utf8"), salt, 10000, dklen=32)
cipher = AES.new(key, AES.MODE_GCM, nonce=vector)
decrypted_data = cipher.decrypt(encrypted_data[:-16]).decode("utf8")
print(decrypted_data)
 
Код:
import base64
import hashlib
from Crypto.Cipher import AES

password = "Caa5f6daa8#.."
cipher_b64 = "CSESV6gQenLzp+AGy9MypU2lBKjxOiCOXUU+xLYkOb8zYGrNOMw0JkgNWW/PH+184k1jYL2phcinsRd+OWidpSAca9z/w1eVpghvVfFYQ0Z6bp54BAxHHZO4DcWcGSBdpKEmAo4S3pzup6wpSnnupaqyImDQl7pwEg1KmqCQSocnKt3DJzzE/MxOW8byKwqh93bkwwIU9aX+/UJU5e23BU8b1bP2WeFc81huGRDyZS5Mz2OmVJAgfqRdBdXcGByLLp6wq/eDdm04vHw23IJdenU42Pdci8Mt4qdKI9ISfjX4RECE70mPpVtCz032CD/QhZdcwiJM1mwDw/7MOLh2OLwxEBHCdFsdzWfa/qpYHAOaJdt5M3TMB6Mu9Z15KkjBBBfm/WCd26JyhBFywmN6QuDuPsED2Nagz2SFFfyFJssMoAcrtzNC1VYh4q/5vdeNoHGh0lKwkXmmKmOat9GVHq8eDgT5RK3yvPaICbvQNCZ6OEOFrAwvt0asW1PfNgLQoLrbCa5et5B+XzUkzISknItDV9panBLIwOBsb9K3GJJ1BcgwOjHPe2u2XkcXwdRlcGGD3imJZnPEd+m+Kv1VbH2lNcKZ5LXZPYFyszr/+7SDO6PYx+7YJB9ewEpc10AYZ/fMnpOAh6ozDpZwMRwapAbOMhZf"
iv_b64 = "zbIzYeha9QW4hjw7eAPyYg=="
salt_b64 = "1In+R0F1apmcIOjpkBDRSm3S65OGI3MV02ECZtU2hRY="

encrypted_data = base64.b64decode(cipher_b64)
salt = base64.b64decode(salt_b64)
vector = base64.b64decode(iv_b64)

key = hashlib.pbkdf2_hmac("sha256", password.encode("utf8"), salt, 10000, dklen=32)
cipher = AES.new(key, AES.MODE_GCM, nonce=vector, mac_len=16) 
decrypted_data = cipher.decrypt_and_verify(encrypted_data[:-16], encrypted_data[-16:])
print(decrypted_data.decode("utf8"))
 
то вполне можно присмотреться к Bcrypt.dll
кстати функции из bcrypt.dll могут и AES-GCM, которым тс пытается декрипнуть пасс
 
Последнее редактирование:
Возможно не в тему, но если вы пишете под Windows, то могу порекомендовать вам использовать криптографические функции из Advapi32.dll, я сумел реализовать AES-256 в режиме CBC с нулевым IV благодаря этой DLL.
Ссылка https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptdecrypt (одна из функций - CryptDecrypt)

А если говорить о чем нибудь поновее, то вполне можно присмотреться к Bcrypt.dll

Мне под линукс
 
А если говорить о чем нибудь поновее, то вполне можно присмотреться к Bcrypt.dll

Пиздёшь. бкрипт стар как сам создатель майкрософта.
 
Bcrypt родила Виста, и на моей семёрке либа датирована 2009-годом.
Список поддерживаемых ею алго на скрине.
В ХР не было AES-256/GCM, а на висте он появился.

bcrypt.png
 
Ап
джпт говорит что ваш код не совсем правильно написан.


Код:
Вы используете strlen для определения длины строки, которая может быть не нулем-терминированной. Это может привести к непредсказуемым результатам. Вместо этого используйте .size() для std::string или .length() для std::vector.

Вы используете strlen для определения длины ключа и вектора инициализации (IV). Это неверно, потому что вы не уверены, что строка нулевого терминатора заканчивается на месте, где ожидается длина. Вместо этого используйте sizeof для массивов и .size() для векторов.

Вы используете strlen для определения длины зашифрованного текста. Это неверно, потому что вы не уверены, что строка нулевого терминатора заканчивается на месте, где ожидается длина. Вместо этого используйте .size() для векторов.

Вы удаляете последние 16 байт из вектора зашифрованного текста, чтобы получить тег. Это неверно, потому что вы не уверены, что последние 16 байт вектора являются тегом. Тег должен быть отдельно передан в фильтр дешифрования.

Вы не уверены, что вы правильно используете AuthenticatedDecryptionFilter. Вы должны передать тег в фильтр дешифрования, а не использовать DEFAULT_FLAGS.

Вот исправленный код: #include <iostream>
#include <vector>
#include <string>
#include "cryptopp/hex.h"
#include "cryptopp/cryptlib.h"
#include "cryptopp/filters.h"
#include "cryptopp/aes.h"
#include "cryptopp/sha.h"
#include "cryptopp/pwdbased.h"
#include "cryptopp/gcm.h"
#include "cryptopp/base64.h"

using namespace CryptoPP;

int main(int argc, char *argv[])
{
    // purpose
    byte unused = 0;

    // password
    byte password[] = "Caa5f6daa8#..";
    size_t plen = strlen((const char *)password);

    // salt
    string salt_b64 = "1In+R0F1apmcIOjpkBDRSm3S65OGI3MV02ECZtU2hRY=";
    string salt_temp;
    StringSource ss(salt_b64, true, new Base64Decoder(new StringSink(salt_temp)));
    const byte *salt = (const byte *)salt_temp.data();
    size_t slen = salt_temp.size();

    // key
    byte key[SHA256::DIGESTSIZE];
    PKCS5_PBKDF2_HMAC<SHA256> pbkdf;
    pbkdf.DeriveKey(key, sizeof(key), unused, password, plen, salt, slen, 10000);

    // iv
    string iv_b64 = "zbIzYeha9QW4hjw7eAPyYg==";
    string iv_temp;
    StringSource ss2(iv_b64, true, new Base64Decoder(new StringSink(iv_temp)));
    const byte *iv = (const byte *)iv_temp.data();
    size_t ivlen = iv_temp.size();

    // cipher
    string cipher_b64 = "..."; // Ваш шифротекст в base64
    string cipher_temp;
    StringSource ss3(cipher_b64, true, new Base64Decoder(new StringSink(cipher_temp)));
    const byte *cipher_full = (const byte *)cipher_temp.data();
    size_t cipher_full_len = cipher_temp.size();

    // tag
    const int TAG_SIZE = 12;
    byte tag[TAG_SIZE];
    memcpy(tag, cipher_full + cipher_full_len - TAG_SIZE, TAG_SIZE);

    // decrypt
    GCM<AES>::Decryption d;
    d.SetKeyWithIV(key, sizeof(key), iv, ivlen);

    string rpdata;
    AuthenticatedDecryptionFilter df(d, new StringSink(rpdata), AuthenticatedDecryptionFilter::DEFAULT_FLAGS, TAG_SIZE);
    df.Put(cipher_full, cipher_full_len - TAG_SIZE);
    df.MessageEnd();
    df.SetTag(tag, TAG_SIZE);

    if (df.GetLastResult()) {
        cout << "Recovered: " << rpdata << endl;
    } else {
        cerr << "Decryption failed" << endl;
    }

    return 0;
}

Обратите внимание, что я удалил последние 16 байт из вектора зашифрованного текста, чтобы получить тег, и я передал тег в фильтр дешифрования. Также я добавил проверку GetLastResult() после дешифрования, чтобы узнать, успешно ли завершилось дешифрование. Если дешифрование не удалось, выводится сообщение об ошибке.
 
джпт говорит что ваш код не совсем правильно написан.


Код:
Вы используете strlen для определения длины строки, которая может быть не нулем-терминированной. Это может привести к непредсказуемым результатам. Вместо этого используйте .size() для std::string или .length() для std::vector.

Вы используете strlen для определения длины ключа и вектора инициализации (IV). Это неверно, потому что вы не уверены, что строка нулевого терминатора заканчивается на месте, где ожидается длина. Вместо этого используйте sizeof для массивов и .size() для векторов.

Вы используете strlen для определения длины зашифрованного текста. Это неверно, потому что вы не уверены, что строка нулевого терминатора заканчивается на месте, где ожидается длина. Вместо этого используйте .size() для векторов.

Вы удаляете последние 16 байт из вектора зашифрованного текста, чтобы получить тег. Это неверно, потому что вы не уверены, что последние 16 байт вектора являются тегом. Тег должен быть отдельно передан в фильтр дешифрования.

Вы не уверены, что вы правильно используете AuthenticatedDecryptionFilter. Вы должны передать тег в фильтр дешифрования, а не использовать DEFAULT_FLAGS.

Вот исправленный код: #include <iostream>
#include <vector>
#include <string>
#include "cryptopp/hex.h"
#include "cryptopp/cryptlib.h"
#include "cryptopp/filters.h"
#include "cryptopp/aes.h"
#include "cryptopp/sha.h"
#include "cryptopp/pwdbased.h"
#include "cryptopp/gcm.h"
#include "cryptopp/base64.h"

using namespace CryptoPP;

int main(int argc, char *argv[])
{
    // purpose
    byte unused = 0;

    // password
    byte password[] = "Caa5f6daa8#..";
    size_t plen = strlen((const char *)password);

    // salt
    string salt_b64 = "1In+R0F1apmcIOjpkBDRSm3S65OGI3MV02ECZtU2hRY=";
    string salt_temp;
    StringSource ss(salt_b64, true, new Base64Decoder(new StringSink(salt_temp)));
    const byte *salt = (const byte *)salt_temp.data();
    size_t slen = salt_temp.size();

    // key
    byte key[SHA256::DIGESTSIZE];
    PKCS5_PBKDF2_HMAC<SHA256> pbkdf;
    pbkdf.DeriveKey(key, sizeof(key), unused, password, plen, salt, slen, 10000);

    // iv
    string iv_b64 = "zbIzYeha9QW4hjw7eAPyYg==";
    string iv_temp;
    StringSource ss2(iv_b64, true, new Base64Decoder(new StringSink(iv_temp)));
    const byte *iv = (const byte *)iv_temp.data();
    size_t ivlen = iv_temp.size();

    // cipher
    string cipher_b64 = "..."; // Ваш шифротекст в base64
    string cipher_temp;
    StringSource ss3(cipher_b64, true, new Base64Decoder(new StringSink(cipher_temp)));
    const byte *cipher_full = (const byte *)cipher_temp.data();
    size_t cipher_full_len = cipher_temp.size();

    // tag
    const int TAG_SIZE = 12;
    byte tag[TAG_SIZE];
    memcpy(tag, cipher_full + cipher_full_len - TAG_SIZE, TAG_SIZE);

    // decrypt
    GCM<AES>::Decryption d;
    d.SetKeyWithIV(key, sizeof(key), iv, ivlen);

    string rpdata;
    AuthenticatedDecryptionFilter df(d, new StringSink(rpdata), AuthenticatedDecryptionFilter::DEFAULT_FLAGS, TAG_SIZE);
    df.Put(cipher_full, cipher_full_len - TAG_SIZE);
    df.MessageEnd();
    df.SetTag(tag, TAG_SIZE);

    if (df.GetLastResult()) {
        cout << "Recovered: " << rpdata << endl;
    } else {
        cerr << "Decryption failed" << endl;
    }

    return 0;
}

Обратите внимание, что я удалил последние 16 байт из вектора зашифрованного текста, чтобы получить тег, и я передал тег в фильтр дешифрования. Также я добавил проверку GetLastResult() после дешифрования, чтобы узнать, успешно ли завершилось дешифрование. Если дешифрование не удалось, выводится сообщение об ошибке.
В примере на питоне тег не используется. Так что вряд ли он там нужен. По поводу strlen там вроде длина байтов, а не строки, я этот метод из доков взял.
 
Пожалуйста, обратите внимание, что пользователь заблокирован


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх