2009-06-26 8 views
1

J'ai une carte à puce Gemalto.NET.
J'ai importé 2 certificats dedans en utilisant les outils de Gemalto, qui utilisent sconnect (qui, comme je le soupçonne, utilise Crypto API pour le faire quand il est utilisé dans IE).CryptGetProvParam PP_ENUMCONTAINERS ne me montre que le certificat par défaut sur la carte à puce

Quand je lance

certutil -key -csp "Microsoft Base Smart Card Crypto Provider" 

Je le résultat suivant

Microsoft Smart Card Base Crypto Fournisseur:
7c168bc3-dc1d-A627-C218-cd45729b42cb [conteneur par défaut] AT_KEYEXCHANGE

badd537a-a377-431b-cbc9-8699dbe15e0eLes clés LoadKeys retournées n'existent pas. 0x8009000d (-2146893811) CertUtil: -la commande par clé s'est terminée avec succès.

Maintenant, je veux trouver ces clés dans mon programme C#. Pour ce faire, j'ai écrit la méthode suivante qui devrait retourner toutes les clés sur une carte à puce spécifique.

static List<string> EnumerateContainers(string card) 
{ 
    var list = new List<string>(); 
    var provider = IntPtr.Zero; 
    if (!CryptAcquireContext(ref provider, @"\\.\" + card + @"\", "Microsoft Base Smart Card Crypto Provider", 1, CspProviderFlags.UseMachineKeyStore)) 
     Debug.WriteLine("no context for " + card); 

    uint bufferSize = 4096; 
    var container = new StringBuilder((int)bufferSize); 
    uint flags = CRYPT_FIRST; 
    while(CryptGetProvParam(provider, PP_ENUMCONTAINERS, container, ref bufferSize, flags)) 
    { 
     list.Add(container.ToString()); 
     flags = 0; 
    } 
    return list; 
} 

Mais ma méthode ne trouve que la clé 7c168bc3-dc1d-A627-C218-cd45729b42cb qui est par défaut. Que faire pour trouver toutes les clés/tous les conteneurs stockés sur la carte à puce?

Et plus tard

Comment puis-je supprimer ces clés et importer nouveau en utilisant C#?

Répondre

1

J'ai rencontré le même problème et j'ai vu des messages similaires sur le web mais finalement j'ai trouvé la réponse ... en vérifiant le code d'erreur!

La raison est que la valeur de pcbData est modifiée par l'implémentation appelée (pour refléter la longueur des données renvoyées) et doit être définie sur la taille de la mémoire tampon avant chaque appel.

La vérification GetLastError après l'échec montre l'erreur 234 qui est exactement celle-là!

En fait, il semble y avoir une propagation d'un bogue dans l'exemple de code de "Extension Cryptography .NET avec CAPICOM et P/Invoke" (http://msdn.microsoft.com/en-us/library/ms867087.aspx)

dwFlags=CRYPT_FIRST; //required initalization 
StringBuilder sb = new StringBuilder(BUFFSIZE); 
while (Win32.CryptGetProvParam(hProv, enumflags, sb, ref pcbData, dwFlags)) 
{ 
    dwFlags=0;   //required to continue entire enumeration 
    containernames.Add(sb.ToString()); 
} 

où il y a pcbData = BUFFSIZE; manquant à l'intérieur de la boucle.

Questions connexes