Back to posts

Powershell: Encrypting strings using [Protect|Unprotect]-CmsMessage

powershellencryptioncertificatesecurity

There are cases we want to encrypt strings, such as passwords.

PowerShell has come a long way, and it supports IETF standard RFD5652 cryptography method using certificate. Note below methods support starting PowerShell version 5.0

Create inf file to generate certificate:

[Version] Signature = "$Windows NT$" [Strings] szOID_ENHANCED_KEY_USAGE = "2.5.29.37" szOID_DOCUMENT_ENCRYPTION = "1.3.6.1.4.1.311.80.1" [NewRequest] Subject = "cn=newcertificate@contoso.com" MachineKeySet = false KeyLength = 2048 KeySpec = AT_KEYEXCHANGE HashAlgorithm = Sha1 Exportable = true RequestType = Cert KeyUsage = "CERT_KEY_ENCIPHERMENT_KEY_USAGE | CERT_DATA_ENCIPHERMENT_KEY_USAGE" ValidityPeriod = "Years" ValidityPeriodUnits = "100" [Extensions] %szOID_ENHANCED_KEY_USAGE% = "{text}%szOID_DOCUMENT_ENCRYPTION%"

We'll call it automation.inf and will use below command to generate and add new certificate to current user:

certreq -new automation.inf automation.cer

It will look something like this:

PS C:\ > certreq -new .\automation.inf c:\scrap\automation.cer Installed Certificate: Serial Number: 50a625ea82fd1b6d44ccc85f441e0604 Subject: CN=newcertificate@contoso.com Thumbprint: 1813dc1407560652482f87bae69cf40bd5953d68 Microsoft Strong Cryptographic Provider 80904f21381e94580d8fe6d24544ec10_4275232e-8c3e-4183-bcd1-b524529f39a3

This will create certificate to desired location, it will also automatically add to current user person certificate store. You can use below command to list recently created/imported certificate:

Get-ChildItem Cert:\CurrentUser\My\ -DocumentEncryptionCert

In case if you like to use different server, and would like to import the public certificate to other server, use below command:

Import-Certificate -FilePath .\auditautomation.cer -CertStoreLocation cert:\CurrentUser\My

Note: There are ways to export private keys to other server. Keep in mind when exporting private key, you need to aware you could potentially risking unprotecting the sensitive private key! It is important to understand you should uncheck "Mark this key as exportable" on other servers.

More info: https://docs.microsoft.com/en-us/powershell/module/pkiclient/export-pfxcertificate?view=win10-ps

Encrypting the string

To encrypt the string, use below commands:

$a = 'ThisIsString123!' $msg = Protect-CmsMessage -Content $a -to .\auditautomation*

Decrypting the string

To decrypt the string, use below commands:

Unprotect-CmsMessage -Content $msg -To Cert:\CurrentUser\My\auditautomation*

If the certificate is imported to local machine:

Unprotect-CmsMessage -Content $msg -To Cert:\LocalMachine\My\auditautomation*

Reference

PowerShell V5 New Feature: Protect/Unprotect-CmsMessage