Программное добавление сертификата в личное хранилище

Проект, над которым я работаю, состоит из веб-сайта MVC, взаимодействующего с веб-службами WCF, аутентифицированного идентификатором Windows. У меня есть сертификат для делегирования удостоверений, который я пытаюсь добавить программно. Чтобы сделать это вручную, я открываю оснастку сертификатов в mmc, импортирую файл .pfx в Personal и ввожу пароль. Затем мне нужно нажать «Управление закрытыми ключами» и разрешить разрешение IIS_IUSRS. Чтобы воспроизвести этот процесс, я придумал следующее консольное приложение:

class Program
{
    static void Main(string[] args)
    {
        var cert = new X509Certificate2("location.pfx", "password", X509KeyStorageFlags.MachineKeySet);
        AddCert(StoreName.My, StoreLocation.LocalMachine, cert);
        AddAccessToCertificate(cert, "IIS_IUSRS");
    }

    private static void AddCert(StoreName storeName, StoreLocation storeLocation, X509Certificate2 cert)
    {
        X509Store store = new X509Store(storeName, storeLocation);
        store.Open(OpenFlags.ReadWrite);
        store.Add(cert);
        store.Close();
    }

    private static void AddAccessToCertificate(X509Certificate2 cert, string user)
    {
        RSACryptoServiceProvider rsa = cert.PrivateKey as RSACryptoServiceProvider;

        if (rsa != null)
        {
            string keyfilepath =
                FindKeyLocation(rsa.CspKeyContainerInfo.UniqueKeyContainerName);

            FileInfo file = new FileInfo(keyfilepath + "\\" +
                rsa.CspKeyContainerInfo.UniqueKeyContainerName);

            FileSecurity fs = file.GetAccessControl();

            NTAccount account = new NTAccount(user);
            fs.AddAccessRule(new FileSystemAccessRule(account,
            FileSystemRights.FullControl, AccessControlType.Allow));

            file.SetAccessControl(fs);
        }
    }
    private static string FindKeyLocation(string keyFileName)
    {
        string text1 =
        Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
        string text2 = text1 + @"\Microsoft\Crypto\RSA\MachineKeys";
        string[] textArray1 = Directory.GetFiles(text2, keyFileName);
        if (textArray1.Length > 0)
        {
            return text2;
        }
        string text3 =
        Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
        string text4 = text3 + @"\Microsoft\Crypto\RSA\";
        textArray1 = Directory.GetDirectories(text4);
        if (textArray1.Length > 0)
        {
            foreach (string text5 in textArray1)
            {
                textArray1 = Directory.GetFiles(text5, keyFileName);
                if (textArray1.Length != 0)
                {
                    return text5;
                }
            }
        }
        return "Private key exists but is not accessible";
    }
}

К сожалению, это дает ошибку:

Адрес издателя токена безопасности не указан. В привязке для цели 'https://service.svc должен быть указан явный адрес эмитента или локальный адрес эмитента. должны быть настроены в учетных данных.

Я признаю, что у меня большой пробел в знаниях по этому вопросу, поэтому я был бы признателен за некоторые советы!

Мой вопрос: в чем разница между моим ручным и автоматизированным процессом?


person NickL    schedule 27.06.2014    source источник


Ответы (1)


Эта строка:

var cert = new X509Certificate2("location.pfx", "password", X509KeyStorageFlags.MachineKeySet);

должны были быть

var cert = new X509Certificate2("location.pfx", "password", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);

Не хватало X509KeyStorageFlags.PersistKeySet.

Я получил полезную информацию о сертификатах отсюда.

person NickL    schedule 21.07.2014