Showing posts with label certutil. Show all posts
Showing posts with label certutil. Show all posts

01 June 2023

Convert .crt and .key file to .pfx without OpenSSL - CertUtil.exe

OMG, you really do learn everyday 😄 

You've been there right, converting a certificate from some format to a pfx file so windows can handle it.Now normally I would turn to OpenSSL, but this is a bit of a hassle with all the commands and not every station you work on has it installed, or you're not allowed to install it.

So there is a standard tool on Windows that is installed by default and is always available that does just this.

Certutil.exe

So how do we go from a .crt file and a .key file to a .pfx?

Place the .crt and .key file in the same directory.

Open cmd.exe as an administrator.

Browse to the path with the .crt and .key file and run:

certutil.exe -mergepfx [inputfile.crt] [outputfile.pfx]

You will have to enter a password and confirm it because the private key is inserted into the .pfx.

And there you have it, without OpenSSL.

03 August 2021

Convert .cer .p12 and .pfx files to .pem files in bulk with PowerShell

One of those things I have to do every year or so, and rather than doing things by hand, let PowerShell help me out.

<#
  .Synopsis
     Covert .cer to .pem 
  .DESCRIPTION
     This script converts .cer, .p12, and .pfx certificate files to .pem files
     Just define the source folder and the target folder
  .Created by
     Edwin van Brenk
  .Created for
     vanbrenk.blogspot.com
  .Date
     03-08-2021
  .Version
     1.0
  #>            
              
            
# Copy your .cer files to the temp dir below                        
mkdir C:\Temp\CerToPEM\cerfolder 2> $null                        
$cerfolder = "C:\Temp\CerToPEM\cerfolder"                        
# Copy your .p12 files to the temp dir below                        
mkdir C:\Temp\CerToPEM\p12folder 2> $null                        
$p12folder = "C:\Temp\CerToPEM\p12folder"                        
# Copy your .pfx files to the temp dir below                        
mkdir C:\Temp\CerToPEM\pfxfolder 2> $null                        
$pfxfolder = "C:\Temp\CerToPEM\pfxfolder"                        
# The new .pem files will end up in this folder                        
mkdir C:\Temp\CerToPEM\pemfolder 2> $null                        
$pemfolder = "C:\Temp\CerToPEM\pemfolder"             
            
            
#Function to convert .cer, .pem, .p12 and .pfx certs to .pem             
function convert {            
            
Get-ChildItem $cerfolder\*.cer | ForEach-Object {            
  certutil -encode $_.FullName ("{0}\{1}.pem" -f $_.DirectoryName,$_.BaseName)            
}            
            
Get-ChildItem $p12folder\*.p12 | ForEach-Object {            
  certutil -encode $_.FullName ("{0}\{1}.pem" -f $_.DirectoryName,$_.BaseName)            
}            
            
Get-ChildItem $pfxfolder\*.pfx | ForEach-Object {            
  certutil -encode $_.FullName ("{0}\{1}.pem" -f $_.DirectoryName,$_.BaseName)            
}            
}            
            
convert            
             
# After converting you can move the .pem files out of the source folder into the .pem destination folder            
Move-Item $cerfolder\*.pem -Destination $pemfolder            
Move-Item $p12folder\*.pem -Destination $pemfolder            
Move-Item $pfxfolder\*.pem -Destination $pemfolder            

30 December 2020

How to cleanup expired certificates from a Microsoft CA with PowerShell and Shrink the DB



This a shameless copy of the original post by André Gibel over at https://www.gibel.net/

The reason why I copied it is because there is very little info on this subject and even though the post is from 2014, it still applies today.

Regularly (depending on the number of issued certificates) you have to perform a clean-up of expired certificates from your CA (Certification Authority) DB and then shrink the DB to get rid of the “white space”.

You have to perform the following 3 steps in order:
1. Make a backup of your CA DB (protected with a password) to another Server / medium





- this backup also "removes" the maybe hundres of db log files (each of the has a size of 1 MB) – in my case 828



2.      Clean-up all expired certificates from all 4 categories  with my PowerShell Script


- in a first step it's the best to run the script in a "view only" modus to see which certificates would be deleted
- the script and all the details are explained 
below.

3.      Shrink your CA database to get rid of the “whitespace”

- for this you use the esentutl tool with the “/d” (= defragmentation) option

Before executing the esentutl command stop the AD Certificate service and disable it




- run the following command with the path to the .edb DB file

esentutl /d "C:\Windows\System32\CertLog\IssuingCA.edb"



- at the end the DB - file is more than 100 MB smaller than before, depending on the size your database is.



- at this point you have to enable and start the CA Service again

Here I explain the PowerShell script in detail (the script is used in step 2)

The Microsoft Enterprise CA I’m responsible for is running on a Microsoft Windows Server 2008 Enterprise Server

- with PowerShell 2.0 installed
- no 3rd party PS modules are used
- the certutil.exe is used by the PowerShell (PS) script
- the PS script I created is "Cleanup_MSPKI_Cert_v1.1.ps1" and contains 3 functions

On this CA Server in the C:\ root drive I create a folder “_scripts “ (I don’t use PS remoting) and copy my PowerShell script “Cleanup_MSPKI_Cert_v1.1.ps1” into this folder


Per default the functions "Remove-ExpiredCertFromDB" writes the temporary files to a subfolder within C:\_scripts\PKICleanupLog.

You can change this default folder path with the parameter  “CleanedFolderLogPath”


The 3 functions I have implemented are:

A.) Get-PublishedCATemplate
B.) Get-IssuedCert
C.) Remove-ExpiredCertFromDB

A.) Get-PublishedCATemplate


When you run this function without a parameter, it displays all Templates from the "Certificate Templates" folder with it's OID. This OID is used by the other to functions to display or delete certificates issued with this certain template. In the following picture you see the corresponding templates from the PKI Snap In



function Get-PublishedCATemplate{             

    [CmdletBinding()]

    Param (

        [parameter()]

        [string]$filter   

    )      

    $FilterLen = ("msPKI-Cert-Template-OID =").length+3   

    $AllPublishedTemplates = Invoke-Expression "certutil.exe –catemplates –v | select-string msPKI-Cert-Template-OID"     

    $AllPublishedTemplates | foreach{       

        $tmp= ($_.line).Substring($FilterLen)       

        $splitarr = $tmp.split(" ",2)     

        $obj = New-Object PSObject                                     

        Add-Member -Input $obj -Name "name" -MemberType Noteproperty -Value $Splitarr[1].trim()

        Add-Member -Input $obj -Name "oid" -MemberType Noteproperty -Value $Splitarr[0].trim()              

        if ($PSBoundParameters["filter"]){  

            if ($Splitarr[1].trim() -match $filter){

                write-output $obj             

            }

        }

        else{

            write-output $obj             

        }

    }              

}

Below I run the script with the -filter parameter and so I only get templates with “SCCM” in their name



I assign the oid of ONE template (=> change filter that you get only one result)  to the variable WSTemplate

$WSTemplate = (Get-PublishedCATemplate -filter workstation).oid


B.) Get-IssuedCert

With this function  you can list the certificates  issued from all templates or a certain template (specified with it’s oid = $CertTemplate variable)  which are issued beginning at a certain date.

 function Get-IssuedCert{

  [CmdletBinding()]

  Param (

    [ValidatePattern('^([0-9\.\s])+$')]

    [string]$CertTemplate,

    [ValidatePattern('^\d\d[\./]{1}\d\d[\./]{1}\d\d\d\d$')]

    [string]$Date

  )

  if ($PSBoundParameters["CertTemplate"]){   

    Invoke-Expression "certutil.exe -view -restrict 'certificate template=$CertTemplate,disposition=20,notbefore>=$Date' -out 'Request.RequestID,Request.RequesterName,NotBefore,NotAfter,Request.Disposition'"       

  }

  else {

    # displays Certificates issued with any custom template   

    Invoke-Expression "certutil.exe -view -restrict 'disposition=20,notbefore>=$Date' -out 'Request.RequestID,Request.RequesterName,NotBefore,NotAfter,Request.Disposition'"             

  }

}

 

The following example lists all  29 certificates (from ALL templates) issued from 18 December 2014 and later …. (with this version it’s not possible to select a time range / only a “start-date”)

Get-IssuedCert  -Date 18.12.2014


The following example lists ONLY the 3 certificates which are issued with the Template $WSTemplate (OID of  “…- Workstation – Authentication Certificate”) beginning December 18. 2014

$WSTemplate = (Get-PublishedCATemplate -filter workstation).oid
Get-IssuedCert -CertTemplate $WSTemplate -Date 18.12.2014



C.) Remove-ExpiredCertFromDB

This is an advanced function and all available parameters are displayed with the get-help command

- the expired certificates to view (1st step) and then delete are in one of 4 folders


- I select this “folder” with the -state parameter


- the script creates a log file (also needed for further parsing) in a separate folder


These folders are created automatically if they don’t exist yet.
In a first step always run the cmdlet without the "-delete" parameter so nothing is really deleted.
I also recommend the ISE instead of the shell.
And I also always run this cmdlet with the “-verbose” parameter.

The following example displays all issued (and expired) certificates till 18.12.2014  --- they are not really deleted yet.

Remove-ExpiredCertFromDB -State issued -Date 18.12.2014  -Verbose 


Without the -delete switch parameter the log file has "-ViewOnly" in it’s name

Below is the output from the example above / 396 entries “would be” deleted from the “issued folder” (or category) if you run the cmdlet with “-delete”


The following example lists / deletes  certificates from a certain (workstation authentication) template expired up to 18 december 2014

$WSTemplate = (Get-PublishedCATemplate -filter workstation).oid
Remove-ExpiredCertFromDB -State issued -CertTemplate $WSTemplate -Date 18.12.2014 -Verbose


With the added-delete switch parameter you really delete the entries
T
his step can take some time if there are a lot of entries.

$WSTemplate = (Get-PublishedCATemplate -filter workstation).oid
Remove-ExpiredCertFromDB -State issued -CertTemplate $WSTemplate -Date 18.12.2014 -Verbose -delete


The output at the end (and the log file)


When  you run the same cmdlet again, you see that there aren’t any entries to delete from the DB



The latest (full) version of this script with the 3 functions you can download from the Microsoft Script Gallery: go to download

DirectDownload link

Since TechNet is retired and will be taken offline any time soon a backup can be downloaded here:

Cleanup_MSPKI_Cert_v1.2.ps1







10 January 2017

Cleaning up the CA database after renewing your Issuing-CA certificate

After renewing your Issuing-CA certificate it's important to clean up your CA internal database.
It can grow quite large, depending on the number of issued certificates of course, but still to keep it as clean and clear as possible works a lot quicker and reduces the chance of errors.

So to clean the CA database we use Certutil.

Clean up the Failed and Pending requests from before 31 January 2016:
Certutil -Deleterow 31/12/2022 Request
Or for an English timezone:
Certutil -Deleterow 12/31/2022 Request

Mind the date notation, this might be different on your system, since i'm in the Netherlands the notation is dd/mm/yyyy, for US it's mm/dd/yyyy.

Clean up the Expired and revoked certificates from before 31 January 2016
Certutil -Deleterow 31/12/2016 Cert

This may take some time as it goes thru all certificates and adds them to the CRL.
Certutil.exe will only delete about 2,000 - 3,000 records at a time before failing due to exhaustion of the version store. This can be solved, wrap this command in a simple batch file (as shown below) that runs the command over and over until all the designated records have been removed.

Batch file:

@echo off

:Top

Certutil -deleterow 31/12/2023 Request

if %ERRORLEVEL% EQU -939523027 goto Top


Or for the Certificates:
@echo off

:Top

Certutil -deleterow 31/12/2023 Cert

if %ERRORLEVEL% EQU -939523027 goto Top