Diskuze: Jak zavolat funkci pro HEX zobrazení výsledku HMAC_SHA1 hashe ?
V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.
Zobrazeno 6 zpráv z 6.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.
Podívej se na prefix prvního formálního parametru metody reportHash() třídy CSHA1.
void ReportHash(char *szReport, unsigned char uReportType = REPORT_HEX);
To sz je tam důležité, jedná se o Maďarskou notaci a
znamená to:
"string of characters terminated by a nul character". Tedy řetezec ukončený
nulovým znakem.
Takže nemůžeš předávat čisté result, neboť to obsahuje pouze data
bez nul.
Musíš předat data spolu s nulovým znakem.
Argument druhého parametru musí být buď REPORT_HEX nebo REPORT_DIGIT. Parametr má inicializaci, pokud jej neuvedeš. Tedy pokud nezadáš nic bude předávaná hodnota REPORT_HEX.
Díky za vysvětlení. Nedává mi to ale moc smysl. szRport
vypadá spíš jako výstupní string, do kterého se bude zapisovat 20 bytů
hashe převedených na HEX viz funkce v SHA1.cpp:
#ifdef SHA1_UTILITY_FUNCTIONS
// Get the final hash as a pre-formatted string
void CSHA1::ReportHash(char* szReport, unsigned char uReportType)
{
unsigned char i;
char szTemp[16];
if (szReport == NULL) return;
if (uReportType == REPORT_HEX)
{
sprintf_s(szTemp, "%02X", m_digest[0]);
strcat_s(szReport, sizeof(szReport), szTemp);
for (i = 1; i < 20; i++)
{
sprintf_s(szTemp, " %02X", m_digest[i]);
strcat_s(szReport, sizeof(szReport), szTemp);
}
}
else if (uReportType == REPORT_DIGIT)
{
sprintf_s(szTemp, "%u", m_digest[0]);
strcat_s(szReport, sizeof(szReport),szTemp);
for (i = 1; i < 20; i++)
{
sprintf_s(szTemp, " %u", m_digest[i]);
strcat_s(szReport, sizeof(szReport), szTemp);
}
}
else strcpy_s(szReport, sizeof(szReport), "Error: Unknown report type!");
}
#endif
Těch 20 bytů hashe se automaticky načítá pomocí
m_digest[i]
Nedává mi to vůbec smysl, proč by se pro výpis hashe měl zadávat nějaký
string, kam se budou HEX data zapisovat.
RAW výsledek lze také uložit jinam pomocí druhé funkce (bez převodu na ASCII HEX):
// Get the raw message digest
void CSHA1::GetHash(UINT_8* puDest)
{
memcpy(puDest, m_digest, 20);
}
"Utility" funkce mi připadá jako naprosto složitý nesmysl. Data jsou po výpočtu uložena v poli result (20 byte) a stačí je jen převést na HEX a vypsat.
Výpis HEX hodnot jsi mi poradil již v jednom z dřívějších dotazů viz
Převod
HEX řetězce na pole bytů
Fakt vůbec nechápu smysluplné použití té utility funkce.
Přesně tak. První parametr vyjadřuje ukazatel na pole, na jehož konec se budou přidávat konverovaná data z m_digest. Ta funkce není napsaná dobře, není důvod používat mezibuffer. Použij tu funkci kterou jsem Ti poslal v článku na který se v příspěvku odkazuješ.
Že je funkce kostrbatá, je to nejmenší. Ve funkci jsou hlavně chyby.
Secure verze funkce sprintf_s() má prototyp:
int sprintf_s(
char *buffer,
size_t sizeOfBuffer,
const char *format,
...
);
ve funkci je ale volána se třemi argumenty, s absencí velikosti bufferu.
Secure verze funkce strcat_s() má následující prototyp:
errno_t strcat_s(
char *strDestination,
size_t numberOfElements,
const char *strSource
);
Ve funkci je ale druhý argument zjišťován pomocí operátoru preprocesoru
sizeof, což je naprostý nesmysl.
Snaha získat velikost objektu postrádá korektnost, neboť pomocí sizeof
akorát určí velikost ukazatele nikoli velikost objektu. Výsledkem výrazu
sizeof(szReport) bude vždy 4, ne však velikost pole do kterého chce data
ukládat.
Díky za upřesnění, pro výpis použiji tvou funkci .
P.S. Pokouším se odhalit, proč mnou naprogramovaná funkce HMAC SHA1 chybně počítá SHA1, pokud je délka zprávy delší než 64 znaků (512 bitů). Pro HMAC (viz implementation) se v kroku 1 doplní klíč nulami na 512 bitů a provede se XOR s 0x36 k tomu se pak v dalším 512 bit bloku přidá message. Podrobně jsem to popsal v jiném fóru.
Zobrazeno 6 zpráv z 6.