Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
0 / 0 / 0
Регистрация: 23.12.2018
Сообщений: 37

Как получить идентификатор алгоритма хеширования латиницей через CryptGetHashParam?

24.03.2022, 16:11. Показов 2197. Ответов 18

Студворк — интернет-сервис помощи студентам
Подскажите, пожалуйста, написал программу, которая хеширует данные из файла и выводит значение хеша и алгоритм хеширования (надо обязательно через функцию CryptGetHashParam, по заданию)
Вот несколько вариантов вывода, которые мне удалось найти в примерах в нете, но и тот и тот не выводят CALG_SHA, который я передавал в функцию CryptCreateHash. Возможно, он так и должен выводить что-то непонятное, я не знаю. Просто думал, что он мне вернет CALG_SHA, а он возвращает ромбик и букву А (первый способ вывести) или 48000 (второй способ вывести), может кто подскажет, в какой кодировке эта функция возвращает id алгоритма в буфер и как мне конвертировать значение буфера в латиницу и вывести на экран.

C++
1
2
3
4
5
6
if (CryptGetHashParam(hashObjectForAlgID, HP_ALGID, buffer1, &SizeOfBuffer, 0)){
    cout << "\n Alg ID: ";
    for (int i = 0; i < SizeOfBuffer;  i++){
        cout << buffer1[i];
    }
}
C++
1
2
3
4
5
6
if (CryptGetHashParam(hashObjectForAlgID, HP_ALGID, buffer1, &SizeOfBuffer, 0)){
    cout << "\n Alg ID: ";
    for (int i = 0; i < SizeOfBuffer;  i++){
        cout << hex << int(buffer1[i]);
    }
}
P.s. Если что могу кинуть полностью код, хотя тут дело не в нем, мне кажется, потому что значение хеша само, у меня корректно выводится как
C++
1
cout << hex << int(buffer2[i]);
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
24.03.2022, 16:11
Ответы с готовыми решениями:

Как получить уникальный идентификатор девайса через SetupDiGetDeviceInterfaceDetail
Всем привет, у меня есть функция, которая по заданному интерфейсному guid пробегается по всем девайсам, предоставляющим этот интерфейс и...

По поводу алгоритма хеширования Md5
Объясните плыз более менее русским языком принцип хеширования, по какому алгоритму это происходит А то в мудреные объяснения и исходники...

Реализация алгоритма хеширования scrypt
Приветствую всех! Подскажите, существует ли реализация алгоритма хеширования scrypt в java?

18
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
25.03.2022, 05:43
Какая ещё кодировка, это не текстовые данные, не буквы, не строки, не символы, это двоичные данные. Вот у вас фильмы и фотокарточки хранятся не в тексте, а двоичными данными. Так и тут.
0
0 / 0 / 0
Регистрация: 23.12.2018
Сообщений: 37
25.03.2022, 10:38  [ТС]
Цитата Сообщение от Замабувараев Посмотреть сообщение
Какая ещё кодировка, это не текстовые данные, не буквы, не строки, не символы, это двоичные данные. Вот у вас фильмы и фотокарточки хранятся не в тексте, а двоичными данными. Так и тут.
Допустим.
Но можно в итоге ответить на вопрос?)
Как мне вывести данные из буфера, чтобы получить идентификатор алгоритма?
Иначе зачем вообще существует параметр HP_ALGID для CryptGetHashParam, если он возвращает в буфер набор непонятных символов? В документации сказано, что возвращает в буфер идентификатор алгоритма, но во всем интернете нет ни 1 примера кода, где кто-то получает через эту функцию идентификатор алгоритма. Это действо само по себе, как мне кажется бесполезно. Потому что для получения через эту функцию идентификатора алгоритма, надо иметь дескриптор хеш-объекта, а если он у нас есть, то вероятно, мы его и создали в рамках программы и, получается, и так знаем алгоритм, который передавали в функцию создания дескриптора.
Но по документации, возможность получить алгоритм есть, и мне нужно это сделать. Но как это сделать, я не знаю. 3й день ищу решение, все тщетно.
МОЛЮ О ПОМОЩИ!
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
25.03.2022, 13:14
Цитата Сообщение от TongueLizard Посмотреть сообщение
если он возвращает в буфер набор непонятных символов?
Каких символов? Нет никаких символов, в буфере который заполнит эта функция, лежат двоичные данные, а не символы.
0
0 / 0 / 0
Регистрация: 23.12.2018
Сообщений: 37
25.03.2022, 14:16  [ТС]
Цитата Сообщение от Замабувараев Посмотреть сообщение
Каких символов? Нет никаких символов, в буфере который заполнит эта функция, лежат двоичные данные, а не символы.
Я это понял уже
Двоичные данные тоже что-то обозначают, это же не рандомные нули и единицы
Как их преобразовать, чтобы получить идентификатор алгоритма
0
0 / 0 / 0
Регистрация: 23.12.2018
Сообщений: 37
25.03.2022, 14:25  [ТС]
Вот скриншот документации, я устанавливаю параметр HP_ALGID, чтобы получить в буфер идентификатор алгоритма, хорошо, он возвращает двоичный код, как преобразовать его в идентификатор, который этот двоичный код означает (а он должен обозначать алгоритм, потому что в документации указано, что в буфер возвращается алгоритм при указании HP_ALGID)
Если указать HP_HASHVAL или HP_HASHSIZE, то в буфер выводятся значения, которые я смог преобразовать к удобному мне виду (то есть хеш в шестнадцатеричных числах, размер хеша в десятичных), но если я пытаюсь преобразовать данные буфера, которые получаю при HP_ALGID, никак не могу получить "CALG_...", чтобы я ни делал
Миниатюры
Как получить идентификатор алгоритма хеширования латиницей через CryptGetHashParam?  
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
26.03.2022, 11:12
Вам по указателю на BYTE функция записывает данные и ещё заполняет сколько байт она туда записала.
Преобразуйте указатель на BYTE, который вы передавали в функцию, в указатель на DWORD или DWORD64 и используйте это число.

Добавлено через 1 минуту
Указатель на DWORD разыменовать — и получите ID алгоритма хеширования.
0
0 / 0 / 0
Регистрация: 23.12.2018
Сообщений: 37
26.03.2022, 14:22  [ТС]
Цитата Сообщение от Замабувараев Посмотреть сообщение
Указатель на DWORD разыменовать — и получите ID алгоритма хеширования.
Не совсем понял, имеете ввиду вот так?
C++
1
2
3
4
5
6
7
8
        SizeOfBuffer = 30;
        if (CryptGetHashParam(hashObjectForAlgID, HP_ALGID, buffer0, &SizeOfBuffer, 0)) {
            cout << "\nAlg ID: ";
            for (int i = 0; i < SizeOfBuffer; i++)
            {
                cout << DWORD(buffer0[i]);
            }
        }
Если можно, покажите на этом кусочке кода
Вот такой код выводит 4 таких байта: 4 80 0 0

buffer0 здесь
C++
1
BYTE* buffer0 = new BYTE;
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
26.03.2022, 15:00
Лучший ответ Сообщение было отмечено TongueLizard как решение

Решение

Во‐первых, вы выделяете недостаточно памяти для буфера. Инструкция BYTE* buffer0 = new BYTE; выделит только один BYTE памяти.
Чтобы понять сколько точно BYTE нужно, следует это узнать:
C++
1
2
DWORD SizeOfBuffer = 0;
CryptGetHashParam(hashObjectForAlgID, HP_ALGID, NULL, &SizeOfBuffer, 0);
После этого выделить память для буфера:
C++
1
BYTE* buffer0 = new BYTE[SizeOfBuffer];
Потом получить данные:
C++
1
CryptGetHashParam(hashObjectForAlgID, HP_ALGID, buffer0, &SizeOfBuffer, 0);
Теперь привести указатель на BYTE в указатель на DWORD:
C++
1
DWORD* id = (DWORD *)buffer0;
Теперь можно разыменовать указатель и вывести на сонсоль:
C++
1
cout << *id;
Не забываем уничтожать ранее выделенную память:
C++
1
delete[] buffer0;
1
0 / 0 / 0
Регистрация: 23.12.2018
Сообщений: 37
26.03.2022, 15:26  [ТС]
Цитата Сообщение от Замабувараев Посмотреть сообщение
1
2
DWORD SizeOfBuffer = 0;
CryptGetHashParam(hashObjectForAlgID, HP_ALGID, NULL, &SizeOfBuffer, 0);
Получается мне надо еще копию сделать хеш объекта, ведь CryptGetHashParam закроет мне объект?
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
26.03.2022, 15:51
Цитата Сообщение от TongueLizard Посмотреть сообщение
Получается мне надо еще копию сделать хеш объекта, ведь CryptGetHashParam закроет мне объект?
Не очень понимаю, вы спутали функции CryptDestroyHash и CryptGetHashParam?
0
0 / 0 / 0
Регистрация: 23.12.2018
Сообщений: 37
26.03.2022, 16:01  [ТС]
Цитата Сообщение от Замабувараев Посмотреть сообщение
Не очень понимаю, вы спутали функции CryptDestroyHash и CryptGetHashParam?
Я немного другое спутал, все нормально, это нельзя CryptHashData вызвать после CryptGetHashParam
Вобщем, код получается такой
C++
1
2
3
4
5
6
7
8
9
10
        if (CryptGetHashParam(hashObjectForAlgID, HP_ALGID, NULL, &SizeOfBuffer, 0)) {
            
            BYTE* buffer1 = new BYTE[SizeOfBuffer];
            if (CryptGetHashParam(hashObjectForAlgID, HP_ALGID, buffer1, &SizeOfBuffer, 0)) {
                cout << "\nAlg ID: ";
                DWORD* id = (DWORD*)buffer1;
                cout << *id;
            }
            delete[] buffer1;
        }
И вот что он выводит
Миниатюры
Как получить идентификатор алгоритма хеширования латиницей через CryptGetHashParam?  
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
26.03.2022, 16:24
Ну вот и получили число какое хотели:
CALG_SHA
0x00008004
SHA hashing algorithm. This algorithm is supported by the Microsoft Base Cryptographic Provider.
Источник:
https://docs.microsoft.com/en-... pto/alg-id
0
0 / 0 / 0
Регистрация: 23.12.2018
Сообщений: 37
26.03.2022, 16:55  [ТС]
Цитата Сообщение от Замабувараев Посмотреть сообщение
Ну вот и получили число какое хотели
Воу, спасибо большое

Добавлено через 22 минуты
Цитата Сообщение от Замабувараев Посмотреть сообщение
delete[] buffer0;
Не знаю, из-за этого или нет, но переделал массивы, с обозначением точного размера, и теперь вылазит ошибка abort() has been cancelled
Если можно, взгляните, пожалуйста, где я налажал
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include <windows.h>
#include <wincrypt.h>
 
using namespace std;
 
static HCRYPTPROV cryptoProvider;
static HCRYPTHASH hashObject;
 
int main()
{
    CryptAcquireContext(&cryptoProvider, NULL, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
    CryptCreateHash(cryptoProvider, CALG_SHA, 0, 0, &hashObject);
 
    string path, data;
    cout << "enter path\n";
    cin >> path;
 
    ifstream in(path);
    if (in.is_open())
    {
        getline(in, data);
    }
    in.close();
 
    BYTE* buffer = new BYTE[data.size()];
    
    for (int i = 0; i < data.size(); i++)
    {
        buffer[i] = data[i];
    }
 
    if (CryptHashData(hashObject, buffer, 0, CRYPT_USERDATA))
    {
        DWORD SizeOfBuffer = 30;
        if (CryptGetHashParam(hashObject, HP_HASHSIZE, buffer, &SizeOfBuffer, 0)) {
            BYTE* buffer0 = new BYTE[int(buffer)];
            if (CryptGetHashParam(hashObject, HP_HASHVAL, buffer0, (DWORD*)&buffer, 0)) {
                cout << "\nSize of hash: " << int(buffer);
                cout << "\nHash value: ";
                for (int i = 0; i < int(buffer); i++)
                {
                    cout << hex << int(buffer0[i]);
                }
            }
            delete[] buffer0;
        }
        if (CryptGetHashParam(hashObject, HP_ALGID, NULL, &SizeOfBuffer, 0)) {
            
            BYTE* buffer0 = new BYTE[SizeOfBuffer];
            if (CryptGetHashParam(hashObject, HP_ALGID, buffer0, &SizeOfBuffer, 0)) {
                cout << "\nAlg ID: ";
                DWORD* id = (DWORD *)buffer0;
                cout << *id;
            }
            delete[] buffer0;
        }
 
        delete[] buffer;
        CryptDestroyHash(hashObject);
        CryptReleaseContext(cryptoProvider, 0);
        return 1;
    }
    else return -1;
}
Добавлено через 3 минуты
Конкретно для строчек 29 и 62, если объявить массив просто BYTE* buffer = new BYTE; и не очищать память, то вылетает исключение, но ошибка эта не вылазит
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
26.03.2022, 17:13
Цитата Сообщение от TongueLizard Посмотреть сообщение
CryptGetHashParam(hashObject, HP_ALGID, NULL, &SizeOfBuffer, 0)
А обнулять SizeOfBuffer кто будет? Если вы отправляете NULL, то и длина буфета должна быть нулю.

Добавлено через 2 минуты
Цитата Сообщение от TongueLizard Посмотреть сообщение
DWORD SizeOfBuffer = 30;
        if (CryptGetHashParam(hashObject, HP_HASHSIZE, buffer, &SizeOfBuffer, 0)) {
Ну и тут тоже разберитесь с действительно длиной буфера и тем значением SizeOfBuffer которое вы отправляете в функцию, наверняка они у вас не совпадают.
1
0 / 0 / 0
Регистрация: 23.12.2018
Сообщений: 37
26.03.2022, 17:19  [ТС]
Цитата Сообщение от Замабувараев Посмотреть сообщение
Ну и тут тоже разберитесь с действительно длиной буфера и тем значением SizeOfBuffer которое вы отправляете в функцию, наверняка они у вас не совпадают.
Так вроде когда не знают длину буфера, можно передать в функцию достаточно большое значение
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
26.03.2022, 17:30
Цитата Сообщение от TongueLizard Посмотреть сообщение
Так вроде когда не знают длину буфера, можно передать в функцию достаточно большое значение
Фундаментальная ошибка.
Когда вы отправляете значение больше длины буфера, то функция будет читать или даже записывать за пределы буфера.
https://ru.wikipedia.org/wiki/... 1%80%D0%B0
0
0 / 0 / 0
Регистрация: 23.12.2018
Сообщений: 37
26.03.2022, 17:44  [ТС]
Цитата Сообщение от Замабувараев Посмотреть сообщение
Фундаментальная ошибка.
Вот так вот подправил
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
 DWORD SizeOfBuffer = 0;
        if (CryptGetHashParam(hashObject, HP_HASHVAL, NULL, &SizeOfBuffer, 0)) {
            BYTE* buffer0 = new BYTE[SizeOfBuffer];
            if (CryptGetHashParam(hashObject, HP_HASHVAL, buffer0, &SizeOfBuffer, 0)) {
                cout << "\nSize of hash: " << SizeOfBuffer;
                cout << "\nHash value: ";
                for (int i = 0; i < SizeOfBuffer; i++)
                {
                    cout << hex << int(buffer0[i]) << " ";
                }
            }
            delete[] buffer0;
        }
Добавлено через 6 минут
И еще вопрос, возможно покажется глупым, но значение вида 0x000... Это число просто? или нечто вроде адреса хранения алгоритма
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
26.03.2022, 18:26
Цитата Сообщение от TongueLizard Посмотреть сообщение
0x000...
В си плас плас принято записывать шестнадцатеричные числа с лидирующим нулём и знаком x.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
26.03.2022, 18:26
Помогаю со студенческими работами здесь

Ошибка в реализации алгоритма хеширования SHA3 (keccak)
Мне нужно реализовать хеширование SHA-3. Вроде все сделал, но выводит неправильный результат. Код писал на основе данной статьи....

Защита программ с помощью алгоритма хеширования md2
Помогите пожалуйста!Мне нужно написать прогу которая бы шифровала и розшифровывала файлы с помощью алгоритма хеширования MD 2.Подскажите...

CryptGetHashParam Как самому сгенерить то, что генерит она?
Привет! Ткнине носом на пример или продемонстрируйте тут, как можно самому сгенерить хэш сумму, получаемому в примере с MSDN снизу в...

Как получить уникальный идентификатор сеанса
1) Как получить уникальный идентификатор СЕАНСА 2) И правильно ли будет хранить этот идентификатор (если конечно его можно получить) в...

Как получить какой-то идентификатор компьютера
Хелп ми, эврибади! Для системы лицензирования программа должна считывать какой-то уникальный идентификатор. Например, серийный номер HDD...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
Отправка уведомления на почту при изменении наименования справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере изменения наименования типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной. . .
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений. 9TO2GP2bpX4 a42b81fb172ffc12ca589c7898261ccb/ https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/ Слева синяя линия -. . .
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
Контроль уникальности заводского номера - вариант №2
Maks 24.03.2026
В отличие от предыдущего варианта добавлено прерывание циклов, также добавлены новые переменные для сохранения контекста ошибки перед прерыванием цикла: Процедура ПередЗаписью(Отказ, РежимЗаписи,. . .
SDL3 для Desktop (MinGW): Вывод текста со шрифтом TTF с помощью библиотеки SDL3_ttf на Си и C++
8Observer8 24.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-text-sdl3-c. zip finish-text-sdl3-cpp. zip
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
Контроль уникальности заводского номера - вариант №1
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере нетипового документа выдачи шин для спецтехники с табличной частью, разработанного в конфигурации КА2. Данные берутся из. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru