在.MSI自定义操作中安装证书无法正常工作

我正在尝试在自定义操作中在本地计算机存储中安装证书。 证书已安装,但当我使用它来查询AWS时,我收到此错误:

对象仅包含密钥对的公共一半。 还必须提供私钥。

安装程序正在升级 ,目标是Windows Vista。

如果我使用单独的.exe来安装完全相同的证书,使用完全相同的代码,它的工作原理。 那么使用Windows Installer安装证书时有什么不同呢?

代码:

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

好吧,至少这个问题为我赢得了一个翻滚徽章……

结果certificate是已安装密钥文件的权限。 我不得不授予所有用户读取权限。

这是我用来授予所有(本地)用户读取权限的代码:

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