Update 03.12.2011: исправлен код записи base64 строки в файл.


С различной периодичностью на ньюсгруппах и англоязычных форумах встречаю вопрос, как экспортировать сертификаты из хранилища (Certificate Store) или сертификаты цифровых подписей файлов в .CER или .DER файл. Сегодня я продемонстрирую простой метод для экспорта этих сертификатов.

На самом деле разница между экспортом сертификата из хранилища сертификатов и подписанного файла заключается только в методе извлечения самого сертификата в x509Certificate2 объект. Давайте начнём с самого простого – экспорт сертификата из хранилища. В PowerShell уже есть свой провайдер для этого хранилища и свой PSDrive:

[↓] [vPodans] dir cert:\ Location : CurrentUser StoreNames : {SmartCardRoot, UserDS, AuthRoot, CA...} Location : LocalMachine StoreNames : {SmartCardRoot, AuthRoot, CA, Trust...} [↓] [vPodans] dir cert:\currentuser Name : SmartCardRoot Name : UserDS Name : AuthRoot Name : CA Name : AddressBook Name : Trust Name : Disallowed Name : My Name : Root Name : TrustedPeople Name : TrustedPublisher Name : REQUEST [↓] [vPodans] dir cert:\currentuser\my Directory: Microsoft.PowerShell.Security\Certificate::currentuser\my Thumbprint Subject ---------- ------- 9C5E4DCEF6598C1298894F62D4BD16E601B8C780 CN=Microsoft Corporation, OU=MOPR, O=Microsoft Corporation, L=Redmond, S=W... 986D375362652FE9E39BA4D042A6B8BA75745998 CN=Administrator, CN=Users, DC=sysadmins, DC=lv 4BB89D732920DD91DE66983DDF2CC4EEC272A802 CN=Administrator, CN=Users, DC=sysadmins, DC=lv 14B931DB4790403CCE2A3D03B62638FC7A0D5F34 CN=Administrator, OU=Administrators, DC=sysadmins, DC=lv [↓] [vPodans]

Если просто посмотреть содержимое Cert:\, то мы увидим там 2 хранилища

  • CurrentUser – представляет хранилище текущего пользователя, т.е. является аналогом графической консоли CertMgr.msc
  • LocalMachine – представляет хранилище локального компьютера и является аналогом графической консоли MMC – Certificates, запущенной в контексте LocalComputer.

Внутри уже видны контейнеры, которые мы видим в виде папок в MMC консоли. А дальше уже хранятся наши сертификаты. Эти сертификаты здесь представлены в виде массива x509Certificate2.

[↓] [vPodans] (dir cert:\currentuser\my)[0].gettype().FullName System.Security.Cryptography.X509Certificates.X509Certificate2 [↓] [vPodans]

Если посмотреть свойства этого объекта через Get-Member, то мы сможем там увидеть метод Export(). Но лучше посмотреть этот метод на MSDN, т.к. он имеет несколько конструкторов: x509Certificate2.Export Method. Из них нас заинтересует только первый конструктор, который Export(X509ContentType). Остальные 2 необходимы для экспорта с паролем (только для PFX). Но, как мы видим из описания метода, нам надо ещё указать x509ContentType объект, который будет указывать нам на тип экспортируемого сертификата. Типы экспортируемых сертификатов можно посмотреть по ссылке: http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509contenttype.aspx или в консоли PowerShell:

[↓] [vPodans] [System.Enum]::GetNames([system.security.cryptography.x509certificates.x509contenttype]) Unknown Cert SerializedCert Pfx Pkcs12 SerializedStore Pkcs7 Authenticode

Нас сейчас будет интересовать только тип Cert (только открытая часть сертификата).

Теперь мы уже знаем достаточно много, чтобы уже начать писать код. Мы сейчас получим объект сертификата, укажем тип экспортируемого сертификата и выполним метод Export():

$cert = (dir cert:\currentuser\My)[0]
$type = [System.Security.Cryptography.X509Certificates.X509ContentType]::Cert
$ExportedData = $cert.Export($type)

Но это ещё не всё. Посмотрите, что у вас находится в переменной $ExportedData! Там на самом деле огромный массив байтов (в среднем более 2-20 тысяч элементов). Это же и указано в описании метода, что он возвращает. Именно массив байтов. Но что с ним делать? Я сам по-началу думал об этом, пока не вспомнил про одну вещь:

Certificate Export Wizard

У нас есть выбор, как экспортировать сертификат – в DER или Base64 кодировке. Когда я писал про PsFCIV, то у меня была такая же ситуация. Hasher у меня так же возвращал массив байтов, который мы сразу же загоняли в Base64 кодировку. В нашем случае потребуется то же самое:

$base64Data = [System.Convert]::ToBase64String($ExportedData)

И на выходе мы молучим длинную Base64 строку, которую уже и нужно экспортировать в файл любым удобным для вас методом:

$base64Data > path\file.cer
Set-Content -Path path\file.cer -Value $base64Data -Encoding Ascii

вы можете убедиться в этом просто открыв .CER файл.  Чтобы получить объект сертификата из цифровой подписи файла, то мы можем просто воспользоваться командлетом Get-AuthenticodeSignature и выбрать свойство SignerCertificate. Если подпись файла дополнительно подписана сертификатом сервера времени, то вы можете использовать так же и свойство TimeStampCertificate:

[↓] [vPodans] $a.SignerCertificate Thumbprint Subject ---------- ------- 9E95C625D81B2BA9C72FD70275C3699613AF61E3 CN=Microsoft Corporation, OU=MOPR, O=Microsoft Corporation, L=Redmond, S=W... [↓] [vPodans] $a = Get-AuthenticodeSignature .\Desktop\EASetup.exe [↓] [vPodans] $a.SignerCertificate Thumbprint Subject ---------- ------- 9E95C625D81B2BA9C72FD70275C3699613AF61E3 CN=Microsoft Corporation, OU=MOPR, O=Microsoft Corporation, L=Redmond, S=W... [↓] [vPodans] $a.TimeStamperCertificate Thumbprint Subject ---------- ------- 4D6F357F0E6434DA97B1AFC540FB6FDD0E85A89F CN=Microsoft Time-Stamp Service, OU=nCipher DSE ESN:85D3-305C-5BCF, OU=MOP... [↓] [vPodans]

В этих свойствах сертификаты уже хранятся в виде объектов x509Certificate2 и дальше их можно экспортировать тем же самым путём, как мы это делали для сертификатов из Certificate Store. Собственно, для извлечения сертификатов из цифровых подписей файлов я написал неплохой скриптик, который добавляет в контекстное меню элемент Export Certificate:

Export Certificate Context menu

и по нажатию на него цифровая подпись будет экспортирована в MyDocs\FileName.ext.cer, где FileName.ext – оригинальное имя файла и к нему просто пристыковывается расширение CER. В скрипте предусмотрены несколько диалоговых окон о состоянии сертификата:

  • файл подписан и хеш файла соответствует хешу в цифровой подписи:

Valid Certificate

  • файл подписан, но хеш файла не соответствует хешу в цифровой подписи:

Hash Mismatch

  • файл не содержит цифровых подписей:

No certificate

В двух последних случаях сертификат не экспортируется никуда по очевидным причинам. И, собственно скрипты-инсталляторы этого контекстного меню с рабочим кодом для:

  • PowerShell 1.0:
  • PowerShell V2:

В следующих статьях я планирую поговорить про импорт сертификатов в Certificate Store, а так же и экспорт сертификатов с закрытыми ключами в PFX файл с использованем Windows PowerShell.

Sunday, September 06, 2009 12:46:46 PM (FLE Daylight Time, UTC+03:00)   Comments [2]    

 

Saturday, December 03, 2011 1:55:30 AM (FLE Standard Time, UTC+02:00)
Столкнулся с проблемой проверки сертификатов на отзыв среди компьютеров всего домена, и соответственно пришел к powershell скрипту. В процессе проверки сертификата пользуюсь стандартной утилитой certutil (она есть на всех компьютерах в домене). В процессе отладки заметил, что если пользоваться связкой

$base64Data = [System.Convert]::ToBase64String($ExportedData)
$base64Data > path\file.cer

то в некоторых случаях(скорее всего, причина 32-bit OS, WinXP SP3) возникает ошибка при попытке проверить этит сертификат:
certutil -verify c:\scripts\1.cer
402.203.0: 0x80070057 (WIN32: 87): ..CertCli Version
LoadCert(Cert) returned ASN1 bad tag value met. 0x8009310b (ASN: 267)
CertUtil: -verify command FAILED: 0x8009310b (ASN: 267)
CertUtil: ASN1 bad tag value met.
301.3160.0: 0x8009310b (ASN: 267)

Поэтому, спасибо, хорошим людям :), было найдено решение:

set-content -value $bytes -encoding byte -path path\file.cer

Saturday, December 03, 2011 12:54:50 PM (FLE Standard Time, UTC+02:00)
Самое правильное, конечно же, это не делать лишних конвертаций в Base64, а писать в бинарном виде сразу:
Set-Content -path path\file.cer -value $bytes -encoding byte
или использовать [io.file]::writeallbytes().
OpenID
Please login with either your OpenID above, or your details below.
Name
E-mail
(will show your gravatar icon)
Home page

Comment (HTML not allowed)  

Enter the code shown (prevents robots):

Live Comment Preview
 · 

All content © 2008 - 2012, Vadims Podāns
"Spaces" Theme provided by: Vadims Podāns
About


E-mail - Send mail to the author(s)
Live Messenger -
For english language visitors
Библиотека
Календарик
<February 2012>
SunMonTueWedThuFriSat
2930311234
567891011
12131415161718
19202122232425
26272829123
45678910

Карта расположения посетителей
Favorites





Fan list



Disclaimer
Вся информация на сайте предоставляется на условиях «как есть», без предоставления каких-либо гарантий и прав.

При использовании материалов c данного сайта ссылка на оригинальный источник обязательна.
Protected by Copyscape Online Plagiarism Scanner