В предыдущих статьях мы с вами уже изучили методы экспорта сертификатов из хранилища Certificate Store в файл:
а так же рассмотрели сопутствующие вопросы. Теперь же предлагаю рассмотреть обратную операцию – добавление сертификатов в cert store из файлов. Этот процесс будет несколько легче, чем экспорт, поэтому я в одном посте покажу импорт всех типов сертификатов (они все используют одну схему).
Для импорта нам потребуется метод x509Certificate.Import(), который так же как и метод Export() имеет несколько конструкторов. Мы можем выбрать один универсальный, который подойдёт нам для всех типов файлов сертификатов и это будет конструктор: X509Certificate2.Import Method (String, SecureString, X509KeyStorageFlags). В качестве аргументов он принимает следующее:
Давайте немного разберёмся с флагами последнего аргумента:
Примечание: вы никогда не должны использовать флаг UserProtected для компьютерных сертификатов, поскольку они используются в контексте LocalSystem и у вас просто не будет возможности ввести пароль для использования этого закрытого ключа.
Т.к. X509KeyStorageFlags на самом деле является перечислителем (enumerator), то создавать его объект не обязательно и флаги можно просто использовать как строки. PowerShell уже сам подобъёт эти флаги к нужному типу данных.
т.к. у нас ещё нет готового объекта сертификатов, то мы его просто создаём:
$certs = New-Object system.security.cryptography.x509certificates.x509certificate2
И в этом объекте у нас будет метод Import(), которым мы уже воспользуемся:
$path = "mycert.pfx" $password = Read-Host "Type password for PFX certificate" -AsSecureString $flags = "UserKeySet, Exportable" $certs.Import($path, $password, $flags)
Обратите внимание, что вы за один раз можете указать несколько флагов для KeyStorage, просто перечислив их через запятую. Теперь $certs у нас содержит x509Certificate2 объект нашего сертификата:
[↓] [vPodans] $certs = New-Object system.security.cryptography.x509certificates.x509certificate2 [↓] [vPodans] $path = "mycert.pfx" [↓] [vPodans] $password = Read-Host "Type password for PFX certificate" -AsSecureString Type password for PFX certificate: * [↓] [vPodans] $flags = "UserKeySet, Exportable" [↓] [vPodans] $certs.Import($path, $password, $flags) [↓] [vPodans] $certs Thumbprint Subject ---------- ------- 0F5157A8342C66493E7B1354530DD7A9F980BC69 CN=vPodans [↓] [vPodans]
как видите, у нас всё случилось, PFX файл был успешно прочитан и помещён в объект x509Certificate2. Но это только половина дела, поскольку этот сертификат пока существует только самом в объекте, но не в хранилище. Для того, чтобы записать объект в хранилище мы должны поработать с хранилищем. За него отвечает класс X509Store. Мы создадим этот объект с нуля и укажем какой именно контейнер в каком хранилище открывать. Для этого мы воспользуемся следующим конструктором: X509Store Constructor (StoreName, StoreLocation). Здесь я подробно останавливаться не буду, поскольку названия хранилищ и контейнеров мы уже рассматривали в одном из предыдущих постов: Простой экспорт сертификатов в PowerShell, в этом посте все контейнеры показаны в первом снимке консоли. В нашем случае StoreName будет My (Personal), а Store Location будет CurrentUser (контекст текущего пользователя):
$store = New-Object system.security.cryptography.X509Certificates.X509Store "My", "CurrentUser"
Создали мы объект хранилища, теперь нам надо его открыть в режиме ReadWrite:
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
Этот флаг открытия хранилища указывать надо обязательно, иначе у вас просто не будет к нему доступа. Теперь когда хранилище открыто, можно методом Add(), который в качестве аргумента принимает только x509Certificate2 объекты (он у нас уже есть в переменной $certs):
$store.Add($certs) $store.Close()
Примечание: MSDN настоятельно рекомендует закрывать хранилище после того, как вы провели с ним необходимые операции.
Вот и всё, собственно, у нас теперь PFX файл был успешно импортирован в хранилище.
Когда вы импортируете сертификаты из p7b (PKCS#7) файла, то в нём может быть несколько сертификатов, поэтому здесь поменяется всего 2 строчки. Поскольку у нас в одном файле может быть несколько сертификатов, то для их чтения из файла будем использовать не x509Certificate2 объект, а специальный массив таких объектов – x509Certificate2Collection, о котором мы уже говорили в предыдущем посте:
$bytes = [System.IO.File]::ReadAllBytes($path) $certs = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection$certs.Import($bytes)
Мы сначала прочитали байтовый массив из файла и засунули его в коллекцию x509Certificate2 объектов. Т.к. сертификатов там несколько, а метод Add() у x509Store за раз может взять только один объект – воспользуемся циклом:
$certs | %{$store.Add($_)}
А в остальном схема импорта p7b файлов будет такая же. Вот и всё, что я хотел рассказать по импорту сертификатов из файлов в хранилище. В принципе, используя эти знания вы уже можете затачивать код под свои нужды, тем более я везде, где это было необходимо, указывал ссылки на MSDN, где вы можете узнать более подробно этот материал. Но чтобы сделать жизнь чуточку проще, я постараюсь написать несколько полезных функций для управлениями сертификатами в PowerShell, что будет весьма актуально для Windows Server 2008 R2 Server Core.
Спасибо за внимание :-)
Comments: