Partilhar via


How to manually set the archive flag for certifictes

If you have to select a certain certificate for authentication for example, you may wonder why several certificates are presented by the UI. Internet Explorer may offer several client authentication certificates while securely connecting to a web site or Outlook presents a number of certificates that can be used for eMail encryption.

One reason for such behavior could be that unnecessarily multiple certificates are available in your certificate store. Multiple certificates for the same purpose can exist if old certificates are not properly archived when new certificates are enrolled. Autoenrollment takes care of the archival process but when certificates are manually enrolled, old certificates are not flagged as archived.

Instead of deleting certificates (what you should never do with encryption certificates) you can just archive them. Unfortunately, the Certificates MMC snap-in provides no way to set the archive flag for a certificate. Therefore, install and use CAPICOM to set the flag for a given certificate with a script. The following script can be used as a sample to archive certificates. CAPICOM is fully documented on https://msdn.microsoft.com/.

Option Explicit

Const CAPICOM_CERTIFICATE_FIND_SHA1_HASH = 0

Const CAPICOM_CURRENT_USER_STORE = 2

Const CAPICOM_STORE_OPEN_READ_WRITE = 1

Const CAPICOM_STORE_OPEN_INCLUDE_ARCHIVED = 256

Dim oArgs

Dim oStore, oCertificates

Set oArgs = Wscript.Arguments

if oArgs.Count <> 1 then

   wscript.echo "Must specify the certificate thumbprint as argument"

   wscript.quit 1

end if

Set oStore = CreateObject("CAPICOM.Store")

oStore.Open CAPICOM_CURRENT_USER_STORE, "My", CAPICOM_STORE_OPEN_READ_WRITE or CAPICOM_STORE_OPEN_INCLUDE_ARCHIVED

Set oCertificates = oStore.Certificates.Find(CAPICOM_CERTIFICATE_FIND_SHA1_HASH, oArgs(0))

if oCertificates.Count = 1 then

   oCertificates(1).Archived = false

end if

oStore.CLose

Set oCertificates = Nothing

Set oStore = Nothing

 

The script requires the thumbprint of the certificate to be archived as command-line parameter, for example

cscript archivecert.vbs “be 46 c0 95 ea 4f b7”

To un-archive existing certificates, just change the line oCertificates(1).Archive=false to oCertificates(1).Archive=true.

Instead using CAPICOM you might also consider the CertificateProvider class in Powershell to manipulate certificate stores.

Also from version 6 on (included in Windows Vista or a more recent Windows version), certutil.exe can be used to archive and un-archive certificates.

To archive a certificate, use Notepad to create a text file Archive.inf that has the following content:

[Properties]
19 = Empty

To remove the archive bit from a certificate, use Notepad to create an INF file that has the following content:

[Properties]
19 =

Then run the following command at a command line for each cert to be archived:

certutil –repairstore –user my [CertificateThumbprint] Archive.inf

In the above command, you can also use a comma-separated list of CertificateThumbprints, if you prefer. If you copy/paste the thumbprint and it includes space characters, the thumbprint must be included in double quotes.

Once a certificate is flagged as archived, it does not appear in the certificates MMC snap-in unless the Archived certificates option is set. Also the certificate selection dialogs in Internet Explorer and Outlook do not show archived certificates.

To show archived certificates with the certificates MMC snap-in do the following:

1. Open the certificates MMC snap-in

2. Select the Certificates – Current User container in the left pane

3. From the menu chose Viewand then Options

4. Mark the option Archived certificates and click OK.

Comments

  • Anonymous
    January 01, 2003
    Here is a Powershell example to set the archive bit on all expired certificates. You have to use the .Net classes directly since the PSprovider is read-only - this allows to open the store in read-write mode. $store = New-Object  System.Security.Cryptography.X509Certificates.X509Store "My","CurrentUser" $store.Open("ReadWrite")  # do not IncludeArchived [System.Security.Cryptography.X509Certificates.X509Certificate2Collection] $certificates = $store.certificates foreach ($cert in $certificates |  where {$.notAfter -lt (Get-Date)})  { $.Set_Archived($true) } $store.Close()

  • Anonymous
    January 01, 2003
    thanks

  • Anonymous
    January 01, 2003
    In response to Jbowles, it appears there is no longer a set_archived method. It appears to have been replaced by an archived property that is settable. The question I have, which may never get an answer on this post, if a server via some process marks a cert as archived, can i simply flip it back the other way and things continue?

  • Anonymous
    May 15, 2014
    For post Vista OS's, the CertUtil command must be run as owner of the certificate, which is the SYSTEM. To do that, PSExec.exe must be run (C:>psexec.exe \localhost -s cmd) to get a command window opened as SYSTEM. The commnd "certutil –repairstore MY [CertificateThumbprint] Archive.inf" can be run. (Note missing "-user" switch) You may need to add the path to the archive.inf file.

  • Anonymous
    January 19, 2017
    Where do you save the .inf files?