OVH Cloud OVH Cloud

probleme PKCS8

1 réponse
Avatar
alexis73
Salut,

Je pense m'adresser au bon groupe bien que je n'ai pas vu grand
chose sur du code C/C++ concernant la Crypto API de windows. M'en voulez
pas au cas ou ;) Je suis un petit nouveau dans ce monde depuis un peu
plus de 2 semaines.
Alors voici mon probleme, je dois signer des données avec la clef
privée contenue dans un beau PKCS8 qui a la description ASN.1 suivante :

PrivateKeyInfo ::= SEQUENCE {
version Version,
privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
privateKey PrivateKey,
attributes [0] IMPLICIT Attributes OPTIONAL }

sans aucuns "attributes".

Pour importer cette clef, j'ai trouvé une fonction qui semble
convernir et qui porte le doux nom suivant "CryptImportPKCS8" et dont le
prototype est :

WINCRYPT32API BOOL WINAPI CryptImportPKCS8(
CRYPT_PKCS8_IMPORT_PARAMS sImportParams,
DWORD dwFlags,
HCRYPTPROV* phCryptProv,
void* pvAuxInfo
);

Mon problem concerne la structure CRYPT_PKCS8_IMPORT_PARAMS :


typedef struct _CRYPT_PKCS8_IMPORT_PARAMS {
CRYPT_DIGEST_BLOB PrivateKey;
PCRYPT_RESOLVE_HCRYPTPROV_FUNC pResolvehCryptProvFunc;
LPVOID pVoidResolveFunc;
PCRYPT_DECRYPT_PRIVATE_KEY_FUNC pDecryptPrivateKeyFunc;
LPVOID pVoidDecryptFunc;

J'ai remplie l'attribut PrivateKey avec le buffer de mon PKCS8, et
d'apres le format de ce pkcs8, je ne pense pas avoir a remplir les deux
derniers attributs(vu que la clef est en clair).
Mon problem concerne plus particulierement le second attribut
"pResolvehCryptProvFunc" et le troisieme "pVoidResolveFunc".

Mes questions sont :

- je ne connais pas trop le system de callback de windows (du moins
pour ce qu'il en dise dans la doc), donc comment remplir ou redefinir
cette callback puisqu'il semble que ce soit ce qui doit etre fait ?
- ai je besoin de me servir du troisieme attribut ?


Apres avoir chercher sur google, les seuls liens dispos sont ceux
de microsoft, c'est a dire deux ou 3 liens.. autant dire que cela ne
m'aide pas beaucoup :( et m'inquiete sur le nombre de personnes qui
utilise cette api ;)

Donc si quelqu'un a un exemple de code ou quelques idees concernant
mon probleme, j'en serai treeeeeees heureux :)


Pour repondre : lebren73_NOSPAM@free.fr sans la partie _NOSPAM


Merci

1 réponse

Avatar
Sylvain
"alexis73" a écrit dans le message de news:
417829c6$0$301$
Salut,

Je pense m'adresser au bon groupe bien que je n'ai pas vu grand
chose sur du code C/C++ concernant la Crypto API de windows. M'en voulez
pas au cas ou ;) Je suis un petit nouveau dans ce monde depuis un peu
plus de 2 semaines.
Alors voici mon probleme, je dois signer des données avec la clef
privée contenue dans un beau PKCS8 qui a la description ASN.1 suivante :

PrivateKeyInfo ::= SEQUENCE {
version Version,
privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
privateKey PrivateKey,
attributes [0] IMPLICIT Attributes OPTIONAL }

sans aucuns "attributes".


ce format est un format d'encodage, pas d'échange; l'échange de la clé est
généralement réalisé en chiffrant cette séquence dans un "safe bag" (cf
PKCS12); le CSP sert alors importer ce fichier qu'il nomme pfx


Pour importer cette clef, j'ai trouvé une fonction qui semble
convernir et qui porte le doux nom suivant "CryptImportPKCS8" et dont le
prototype est :

WINCRYPT32API BOOL WINAPI CryptImportPKCS8(
CRYPT_PKCS8_IMPORT_PARAMS sImportParams,
DWORD dwFlags,
HCRYPTPROV* phCryptProv,
void* pvAuxInfo
);

cette fonction est non documentée dans le MSDN et donc source de perte de

temps car vous ne trouverez pas d'info sur son utilisation; je doute même
que le CSP M$ implémente un traitement pour votre cas.


Mon problem concerne la structure CRYPT_PKCS8_IMPORT_PARAMS :


typedef struct _CRYPT_PKCS8_IMPORT_PARAMS {
CRYPT_DIGEST_BLOB PrivateKey;
PCRYPT_RESOLVE_HCRYPTPROV_FUNC pResolvehCryptProvFunc;
LPVOID pVoidResolveFunc;
PCRYPT_DECRYPT_PRIVATE_KEY_FUNC pDecryptPrivateKeyFunc;
LPVOID pVoidDecryptFunc;

J'ai remplie l'attribut PrivateKey avec le buffer de mon PKCS8, et
d'apres le format de ce pkcs8, je ne pense pas avoir a remplir les deux
derniers attributs(vu que la clef est en clair).
Mon problem concerne plus particulierement le second attribut
"pResolvehCryptProvFunc" et le troisieme "pVoidResolveFunc".

Mes questions sont :

- je ne connais pas trop le system de callback de windows (du moins
pour ce qu'il en dise dans la doc), donc comment remplir ou redefinir
cette callback puisqu'il semble que ce soit ce qui doit etre fait ?
- ai je besoin de me servir du troisieme attribut ?



une callback est un méthode à vous (statique et, généralement, en convention
d'appel "__stdcall") qui sera invoqué durant le process de la fonction
appellé, pour cela vous transmettez comme paramètre de cette 1ière fonction
l'adresse de votre fonction (syntaxiquement vous indiquez son nom).

vous codez par exemple:

BOOL __stdcall myDecryptFunction(
CRYPT_ALGORITHM_IDENTIFIER algorithm,
CRYPT_DATA_BLOB encryptedPrivateKey,
byte* pbClearTextKey, DWORD* plainKeyLength,
void* myParam)
{
...
}

puis

CRYPT_PKCS8_IMPORT_PARAMS params;
params.PrivateKey = myBlob;
params.pResolvehCryptProvFunc = null;
params.pVoidResolveFunc = null;
params.pDecryptPrivateKeyFunc = myDecryptFunction;

long myLong = 123L;
params.pVoidDecryptFunc = (void*) &myLong;

pVoidDecryptFunc est un paramètre applicatif qui sera transmis à votre
fonction callback.

lorsque vous appellez:

CryptImportPKCS8(params, 0, null, null);

celle-ci appellera votre fonction en assignant au paramètre "myParam"
l'adresse &myLong.

Une fois passée ces étapes, soit vous êtes chanceux et le CSP M$ a daigné
stocker votre clé, soit vous tentez votre chance avec une autre CSP un peu
mieux documenté.

Dans le même temps, et puisque votre clé est en clair (qui mettrait des
vrais clés dans un CSP soft BTW) vous pouvez essayer de la charger
directement via CryptSetKeyParam qui pourrait vous permettre de charger
votre clé ... si elle était correctement documentée également.


L'autre approche (plus simple et surement plus formatrice) puisque vous
"devez signer des données avec la clef privée contenue dans un beau PKCS8"
est simplement de coder vous même cette génération de signature, une petite
librarie BigInteger dispo sur le net vous aidera ou un code en Java
(disposant d'une telle classe) vous permettra de progresser rapidement.

Sylvain.