2009-09-06 81 views
6

我試圖在自定義操作中的本地計算機存儲中安裝證書。 將證書安裝,但是當我用它來查詢AWS,我得到這個錯誤:在.MSI中安裝證書自定義操作無法正常工作

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

安裝程序運行升高,目標是Windows Vista中。

如果我使用單獨的.exe來安裝完全相同的證書,使用完全相同的代碼,它的工作原理。 那麼,使用Windows安裝程序安裝證書時它有什麼不同?

代碼:

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"); 
    } 
} 

回答

5

嗯,至少這個問題,我贏得了一個翻滾雜草徽章......

它竟然是在安裝密鑰文件的權限。我必須授予所有用戶讀取權限。

這裏是我用來授予所有(本地)用戶讀取權限代碼:

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"; 
}