2017-08-28 4 views
0

J'ai le code ci-dessous. Je mets une prime pour l'algorithme de diffie-hellman en utilisant char *. Je reçois de mauvaises données après avoir défini le premier. Où est-ce que je fais mal? J'ai suivi le même exemple dans ce lien. NTE_BAD_DATA dans CryptSetKeyParam lors de la configuration de KP_P dans wincrypt

Quelle est la bonne façon de définir prime dans diffie-hellman en utilisant wincrypt?

#define DHKEYSIZE 1024 
int fld_sz = 256; 
BYTE* g_rgbPrime = new BYTE[DHKEYSIZE/8]; 
char * prime = "A1BD60EBD2D43C53FA78D938C1EF8C9AD231F9862FC402739302DEF1B6BEB01E5BE59848A04C48B0069A8FB56143688678F7CC1097B921EA3E13E1EF9B9EB5381BEFDE7BBF614C13827493A1CA31DA76B4083B62C5073451D6B1F06A2F1049C291464AC68CBB2F69474470BBAD374073392696B6447C82BF55F20B2D015EB97B"; 
string s_prime(prime, fld_sz); 
vector<std::string> res; 
// split the string two charactes for converting into hex format 
for (size_t i = 0; i < fld_sz; i += 2) 
    res.push_back(s_prime.substr(i, 2)); 
for(int i = 0; i < res.size(); i++) { 
    BYTE b = static_cast<BYTE>(std::stoi(res[i], 0, 16)); 
    g_rgbPrime[i] = b; 
} 
BYTE g_rgbGenerator[128] = 
{ 
    0x02 
}; 
BOOL fReturn; 
HCRYPTPROV hProvParty1 = NULL; 
HCRYPTPROV hProvParty2 = NULL; 
CRYPT_DATA_BLOB P; 
CRYPT_DATA_BLOB G; 
HCRYPTKEY hPrivateKey1 = NULL; 
HCRYPTKEY hPrivateKey2 = NULL; 
PBYTE pbKeyBlob1 = NULL; 
PBYTE pbKeyBlob2 = NULL; 
HCRYPTKEY hSessionKey1 = NULL; 
HCRYPTKEY hSessionKey2 = NULL; 
PBYTE pbData = NULL; 

/************************ 
Construct data BLOBs for the prime and generator. The P and G 
values, represented by the g_rgbPrime and g_rgbGenerator arrays 
respectively, are shared values that have been agreed to by both 
parties. 
************************/ 
P.cbData = DHKEYSIZE/8; 
P.pbData = (BYTE*)(g_rgbPrime); 

G.cbData = DHKEYSIZE/8; 
G.pbData = (BYTE*)(g_rgbGenerator); 

/************************ 
Create the private Diffie-Hellman key for party 1. 
************************/ 
// Acquire a provider handle for party 1. 
fReturn = CryptAcquireContext(
    &hProvParty1, 
    NULL, 
    MS_ENH_DSS_DH_PROV, 
    PROV_DSS_DH, 
    CRYPT_VERIFYCONTEXT); 
if(!fReturn) 
{ 
    goto ErrorExit; 
} 

// Create an ephemeral private key for party 1. 
fReturn = CryptGenKey(
    hProvParty1, 
    CALG_DH_EPHEM, 
    DHKEYSIZE << 16 | CRYPT_EXPORTABLE | CRYPT_PREGEN, 
    &hPrivateKey1); 
if(!fReturn) 
{ 
    goto ErrorExit; 
} 

// Set the prime for party 1's private key. 
fReturn = CryptSetKeyParam(
    hPrivateKey1, 
    KP_P, 
    (PBYTE)&P, 
    0); 
if(!fReturn) 
{ 
    std::cout << GetLastError() << endl; 
    goto ErrorExit; 
} 

// Set the generator for party 1's private key. 
fReturn = CryptSetKeyParam(
    hPrivateKey1, 
    KP_G, 
    (PBYTE)&G, 
    0); 
if(!fReturn) 
{ 
    std::cout << GetLastError() << endl; 
    goto ErrorExit; 
} 

Merci d'avance.

Mise à jour 1: Grâce à @RbMm, j'ai pu définir l'amorçage. Le problème était avec DHKEYSize. Cependant, je reçois une erreur lors de la configuration KP_X. mis à jour le code ci-dessus pour refléter le nouveau code.

Ici, j'ai converti la chaîne en tableau hexadécimal.

Répondre

1

taille du premier KP_P (et KP_G) et taille de la clé DH connectée en dur. doit être cbKey == 8*cbP. par exemple

comme taille de clé si utilisé cbP * 8cbP taille du premier P. dans votre lien aussi P.cbData = DHKEYSIZE/8;

également dans le code à la place taille dur code de P (et G) vous pouvez l'obtenir dans l'exécution:

ULONG dwDataLen; 
CryptGetKeyParam(hPrivateKey1, KP_P, 0, &(dwDataLen = 0), 0); 
CryptGetKeyParam(hPrivateKey1, KP_G, 0, &(dwDataLen = 0), 0); 

et vous pouvez assurer que dwDataLen == DHKEYSIZE/8DHKEYSIZE est taille de la clé.

car vous utilisez 512 comme taille de clé, la longueur de données pour P et G doit être 512/8=64. mais vous utilisez 256 (pour P) et 1 (pour G). comme résultat et erreur.

+0

Merci [RbMm] (https://stackoverflow.com/users/6401656/rbmm). Il a résolu le problème. Mais je n'ai pas le générateur et le premier de la même longueur. Le générateur a une longueur de 1 octet et le premier a une longueur de 128 octets. dans ce cas, comment utiliser cette valeur de générateur d'un octet? –

+0

@PrakashN - pour générer de nouveaux ** P ** et ** G ** vous ne devez pas utiliser l'indicateur 'CRYPT_PREGEN' et le code suivant:' CryptGetKeyParam (hPrivateKey1, KP_P, 0, & (P.cbData = 0), 0) && CryptGetKeyParam (hPrivateKey1, KP_P, P.pbData = (PBYTE) allocation (P.cbData), & P.cbData, 0) && CryptGetKeyParam (hPrivateKey1, KP_G, 0, & (G.cbData = 0), 0) && CryptGetKeyParam (hPrivateKey1, KP_G, G.pbData = (PBYTE) alloca (G.cbData), & G.cbData, 0) '- donc générez et obtenez d'un côté, et d'un autre côté utilisez' CRYPT_PREGEN' et ceci ** P ** et ** G ** – RbMm

+0

Merci RbMm. Dans mon cas, le serveur a déjà convenu des valeurs P et G. donc j'ai besoin d'utiliser les valeurs P et G générées par le serveur pour générer la clé secrète a. j'obtiens l'erreur NTE_BAD_KEY dans CryptSetKeyParam de KP_X. Veuillez nous conseiller –