Diskuze: Algoritmus PBKDF2-HMAC-SHA-256
V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.

Člen

Zobrazeno 12 zpráv z 12.
//= 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.
Trochu jsem otestoval GPU v notebooku:
CUDA Device Query (Runtime API) version (CUDART static linking)
Detected 1 CUDA Capable device(s)
Device 0: "NVIDIA GeForce GTX 960M"
CUDA Driver Version / Runtime Version 11.8 / 11.8
CUDA Capability Major/Minor version number: 5.0
Total amount of global memory: 4096 MBytes (4294836224 bytes)
(005) Multiprocessors, (128) CUDA Cores/MP: 640 CUDA Cores
GPU Max Clock rate: 1176 MHz (1.18 GHz)
Memory Clock rate: 2505 Mhz
Memory Bus Width: 128-bit
L2 Cache Size: 2097152 bytes
Maximum Texture Dimension Size (x,y,z) 1D=(65536), 2D=(65536, 65536), 3D=(4096, 4096, 4096)
Maximum Layered 1D Texture Size, (num) layers 1D=(16384), 2048 layers
Maximum Layered 2D Texture Size, (num) layers 2D=(16384, 16384), 2048 layers
Total amount of constant memory: 65536 bytes
Total amount of shared memory per block: 49152 bytes
Total shared memory per multiprocessor: 65536 bytes
Total number of registers available per block: 65536
Warp size: 32
Maximum number of threads per multiprocessor: 2048
Maximum number of threads per block: 1024
Max dimension size of a thread block (x,y,z): (1024, 1024, 64)
Max dimension size of a grid size (x,y,z): (2147483647, 65535, 65535)
Maximum memory pitch: 2147483647 bytes
Texture alignment: 512 bytes
Concurrent copy and kernel execution: Yes with 4 copy engine(s)
Run time limit on kernels: No
Integrated GPU sharing Host Memory: No
Support host page-locked memory mapping: Yes
Alignment requirement for Surfaces: Yes
Device has ECC support: Disabled
CUDA Device Driver Mode (TCC or WDDM): WDDM (Windows Display Driver Model)
Device supports Unified Addressing (UVA): Yes
Device supports Managed Memory: Yes
Device supports Compute Preemption: No
Supports Cooperative Kernel Launch: No
Supports MultiDevice Co-op Kernel Launch: No
Device PCI Domain ID / Bus ID / location ID: 0 / 1 / 0
Compute Mode:
< Default (multiple host threads can use ::cudaSetDevice() with device simultaneously) >
deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 11.8, CUDA Runtime Version = 11.8, NumDevs = 1
Result = PASS
a
CUDA Clock sample
> Using CUDA Device [0]: NVIDIA GeForce GTX 960M
> Using CUDA Device [0]: NVIDIA GeForce GTX 960M
> GPU Device has SM 5.0 compute capability
Average clocks/block = 4612.875000
Teď musím zjistit, jak naprogramovat ty dvě funkce a pak spustím výpočet klíče na max. počtu paralelních vláken.
Ještě se vrátím k mého prvnímu příspěvku na začátku. Program se ve Visual Studiu 2022 přeloží, ale hlásí mi dvě chyby:
Závažnost Kód Popis Projekt Soubor Řádek Stav potlačení
Upozornění C4267 argument: Převod z: size_t na: int, může dojít ke ztrátě dat. PBKDF2-HMAC-SHA-256 řádek 20
Závažnost Kód Popis Projekt Soubor Řádek Stav potlačení
Chyba C4996 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. PBKDF2-HMAC-SHA-256 řádek 22
Jak program upravit, aby chyby zmizely ?
size_t je bezznaménkový celočíselný typ, int je znaménkový. Pokud se typ používá pro indexování pole nebo v cyklech, používá se size_t. Pravděpodobně porovnávaš proměnné obou typů proto Ti překladač vyhazuje toto varování. Pokud hodnota která se vejde do size_t i zároveň do int, pak je vše ok, pokud ovšem hodnota bude vyšší, dojde k přetečení a hodnoty obou typů by byly odlišné. Tedy pokud funkce vrací size_t, použij proměnnou typu size_t i na levé straně přiřazovacího příkazu. Pokud funkce vrací int a hodnota bude záporná, nelze tuto hodnotu vyjádřit pomocí proměnné typu size_t.
U druhého případu použij buď funkci sprintf_s() nebo definuj makro _CRT_SECURE_NO_WARNINGS pomocí direktivy preprocesoru #define.
S tou proměnnou tomu sice rozumím, ale nechápu jak a kde to v programu opravit. Po přídání _CRT_SECURE_NO_WARNINGS do vlastností projektu (C++, Obecné, Preprocesor, Definice preprocesoru) sice druhá chyba zmizela (#define _CRT_SECURE_NO_WARNINGS v kódu programu hlásilo chybu), ale objevily se 2 nové:
Závažnost Kód Popis Projekt Soubor Řádek Stav potlačení
Chyba LNK2001 Nerozpoznaný externí symbol EVP_sha256 PBKDF2-HMAC-SHA-256 Řádek 1
Závažnost Kód Popis Projekt Soubor Řádek Stav potlačení
Chyba LNK2001 Nerozpoznaný externí symbol PKCS5_PBKDF2_HMAC PBKDF2-HMAC-SHA-256 Řádek 1
Ve vlastnostech projektu jsem samozřejmě nastavil:
C++, Obecné, Další adresáře k zahrnutí: C:\Program Files\FireDaemon
OpenSSL 3\include
Linker, Obecné, Další adresáře knihoven: C:\Program Files\FireDaemon
OpenSSL 3\lib
Na řádku 1 je přitom jen:
// PBKDF2-HMAC-SHA-256.cpp
Kód jsem použil a trochu upravil z odkazu zde
Změníš to v deklaraci proměnné.
Máš-li proměnnou var deklarovanou jako:
int var;
pak to změníš na:
size_t var;
Ve funkcích scanf() a printf() používáš pro size_t specifikaci formátu %zu.
Potřebuješ ještě konkretizovat knihovny lib. Takže do Linker/Input/Aditional dependencies vlož patřičné lib soubory.
Díky, přidání těch konkrétních knihoven do projektu pomohlo, chyby zmizely a program už něco spočítal:
50e7a5fb23a9f47f0d2822df485691240c7dd9de2c5261c49d25fa18110d7465
Musím ale prověřit, zda to počítá správně, jestli jsme použil správné funkce. WPA key calculation dá jiný výsledek.
S tou proměnnou int to ale stále hlásí upozornění. Zkusil jsem řádek 20 změnit na:
size_t int i;
pak mi to ale hlásilo "neplatná kombinace specifikátorů typu". Že by to chtělo na řádku 11 změnit definici ?
int32_t iterations = 4096;
size_t je typ, totéž co int, char, float, double. Není to modifikátor. Nelze tedy kombinovat dva typy naráz ale pouze jeden se jménem proměnné.
Projdi si celý program, zkontroluj typy vrácených hodnot, datové typy všech proměnných které používáš a jejich korespondovani s typy parametrů ve funkcích.
S tou dvojí definicí int jsem se jen překlepl .
Podíval jsem se na definici funkce PKCS5_PBKDF2_HMAC a zjistil, že musím přetypovat délky řetězců z size_t na int viz:
PKCS5_PBKDF2_HMAC(pass, (int)strlen(pass), (const unsigned char*)salt, (int)strlen(salt), iterations, EVP_sha256(), outputBytes, digest);
Všechny chyby a varování teď zmizely a program funguje .
Dost zvláštní a trochu nešťastné, že používají pro délku řetězce datový typ int a nikoli size_t, který je návratovým typem funkce strlen(). Pak stačí prosté přetypování na daný datový typ, neboť rozsah int je pro celá čísla menší nežli rozsah typu size_t.
Prima, fajn že vše funguje. 😊
Díky za skvělou pomoc .
PSK už to počítá správně. V parametrech funkce bylo potřeba jen změnit
EVP_sha256 na EVP_sha1.
Teď budu řešit PMK = PBKDF2(HMAC−SHA1, PSK, SSID, 4096, 256) tj. Pairwise Master Key
Kód generující správný výsledek:
#include <iostream>
#include <openssl/evp.h>
#include <openssl/sha.h>
// crypto.h used for the version
#include <openssl/crypto.h>
int32_t iterations = 4096;
const char* pass = "radiustest";
const char* salt = "linksys54gh";
uint32_t outputBytes = 32;
void PBKDF2_HMAC_SHA_256_string(const char* pass, const char* salt, int32_t iterations, uint32_t outputBytes, char* hexResult)
{
unsigned int i;
unsigned char digest[0x20];
PKCS5_PBKDF2_HMAC(pass, (int)strlen(pass), (const unsigned char*)salt, (int)strlen(salt), iterations, EVP_sha1(), outputBytes, digest);
//printf("%d\n", sizeof(digest));
for (i = 0; i < sizeof(digest); i++)
sprintf(hexResult + (i * 2), "%02x", 255 & digest[i]);
}
int main()
{
// 2*outputBytes+1 is 2 hex bytes per binary byte,
// and one character at the end for the string-terminating \0
char hexResult[2 * 32 + 1];
memset(hexResult, 0, sizeof(hexResult));
PBKDF2_HMAC_SHA_256_string(pass, salt, iterations, outputBytes, hexResult);
printf_s("%s\n", hexResult);
//Result should be: 9e9988bde2cba74395c0289ffda07bc41ffa889a3309237a2240c934bcdc7ddb
}
Zobrazeno 12 zpráv z 12.