2009-09-06 11 views
6

Je tente d'installer un certificat dans le magasin de la machine locale dans une action personnalisée. Le certificat est installé, mais quand je l'utilise pour interroger AWS, je reçois cette erreur:L'installation d'un certificat dans une action personnalisée .MSI ne fonctionne pas correctement

Object contains only the public half of a key pair. A private key must also be provided.

Le programme d'installation est en cours d'exécution surélevée, la cible est Windows Vista.

Si j'utilise un fichier .exe distinct pour installer exactement le même certificat, en utilisant exactement le même code, cela fonctionne. Qu'est-ce qui diffère lors de l'installation d'un certificat à l'aide de Windows Installer?

Le code:

private void InstallCertificate(string certificatePath, string certificatePassword) 
{ 
    if (IsAdmin()) 
    { 
    try 
    { 
     X509Certificate2 cert = new X509Certificate2(certificatePath, certificatePassword, 
     X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet); 

     X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine); 
     store.Open(OpenFlags.ReadWrite); 
     store.Add(cert); 
     store.Close(); 
    } 
    catch (Exception ex) 
    { 
     throw new DataException("Certificate appeared to load successfully but also seems to be null.", ex); 
    } 
    } 
    else 
    { 
    throw new Exception("Not enough priviliges to install certificate"); 
    } 
} 

Répondre

5

Eh bien, au moins cette question m'a valu un badge weed linge ...

Il est avéré être les autorisations sur le fichier clé installée. Je devais accorder à tous les utilisateurs des autorisations de lecture.

Et voici le code que je l'habitude d'accorder à tous les utilisateurs (locales) les autorisations de lecture:

private static void AddAccessToCertificate(X509Certificate2 cert) 
{ 
    RSACryptoServiceProvider rsa = cert.PrivateKey as RSACryptoServiceProvider; 
    if (rsa == null) return; 

    string keyfilepath = FindKeyLocation(rsa.CspKeyContainerInfo.UniqueKeyContainerName); 

    FileInfo file = new FileInfo(System.IO.Path.Combine(keyfilepath, rsa.CspKeyContainerInfo.UniqueKeyContainerName)); 

    FileSecurity fs = file.GetAccessControl(); 

    SecurityIdentifier sid = new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null); 
    fs.AddAccessRule(new FileSystemAccessRule(sid, FileSystemRights.Read, AccessControlType.Allow)); 
    file.SetAccessControl(fs); 
} 

private static string FindKeyLocation(string keyFileName) 
{ 
    string pathCommAppData = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), @"Microsoft\Crypto\RSA\MachineKeys"); 
    string[] textArray = Directory.GetFiles(pathCommAppData, keyFileName); 
    if (textArray.Length > 0) return pathCommAppData; 

    string pathAppData = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"Microsoft\Crypto\RSA\"); 
    textArray = Directory.GetDirectories(pathAppData); 
    if (textArray.Length > 0) 
    { 
    foreach (string str in textArray) 
    { 
     textArray = Directory.GetFiles(str, keyFileName); 
     if (textArray.Length != 0) return str; 
    } 
    } 
    return "Private key exists but is not accessible"; 
}