OpenPGP in PowerShell

DidiSoft OpenPGP Library for .NET provides a compiled module with Windows PowerShell commands.

The module is installed in %UserProfile%\Documents\WindowsPowerShell\Modules in subfolder DidiSoft.Pgp.PowerShell and the Cmldets are available in your PowerShell console. Additionally, it can be found under the library setup folder\Bin\PowerShell.

Table of Contents

Encrypting

The encryption is done through the command ConvertTo-PgpEncryptedFile, here is how to perform it with a key in a file:

1
ConvertTo-PgpEncryptedFile -Path C:\INPUT.txt -Key C:\recipient_key.asc -Output c:\encrypted.pgp

Additional parameters are:
-AsciiOutput – boolean value that controls should the output be in OpenPGP ASCII armored format (true) or binary format (false)
-IntegrityProtect – a boolean value that controls should the output be protected with a Modification detection code (true) or not (false). (true by default)

Encrypting with a public key from a KeyStore

We can also encrypt using a public key located in a KeyStore file:

1
ConvertTo-PgpEncryptedFile -Path C:\INPUT.txt -KeyStore c:\my.keystore -KeyStorePassword "pass123" -Key "acm@company.com" -Output c:\encrypted.pgp

The desired encryption key can be specified through the -Key parameter, either with part of the User ID (like “acm@company.com”) or with the hexadecimal Key ID (like “A34BC271”)
The KeyStore password can also be specified as a SecureString with the -SecureKeyStorePassword parameter instead!

Encrypting with a public key from PGP/GnuPG key ring

Having an existing Symantec PGP command line or GnuPG/gpg installation we can reuse keys directly from there with the -Pubring parameter like:

1
ConvertTo-PgpEncryptedFile -Path C:\INPUT.txt -Pubring c:\GnuPG\pubring.gpg -Key "acm@company.com" -Output c:\encrypted.pgp

 

Decrypting

The decryption command is ConvertFrom-PgpEncryptedFile. Below is an example:

1
ConvertFrom-PgpEncryptedFile -Path C:\encrypted.pgp -Key C:\my_private_key.asc -Password "my key password" -Output c:\data.txt

Decrypting with a key from a KeyStore

If our private key resides in a KeyStore, we have to specify it with the -KeyStore parameter, instead of the -Key parameter:

1
ConvertFrom-PgpEncryptedFile -Path C:\encrypted.pgp -KeyStore C:\my.keystore -KeyStorePassword "my key store password" -Password "my key password" -Output c:\data.txt

Both the KeyStore password and key own password can be specified as SecureString (-SecureKeyStorePassword and -SecurePassword parameters).

Decrypting with a key from a PGP/GnuPG key ring

Having an existing PGP/GnuPG installation we can reuse private keys from there with the -Secring parameter:

1
ConvertFrom-PgpEncryptedFile -Path C:\encrypted.pgp -Secring C:\GnuPG\secring.gpg -Password "my key password" -Output c:\data.txt

Signing and verifying

The OpenPGP signed-only format combines the data with the digital signature in one file. For this purpose, we use the command ConvertTo-PgpSignedFile for signing.

ConvertTo-PgpSignedFile -Path C:\INPUT.txt -Key C:\my_private_key.asc -Password "my key password" -Output c:\signed.pgp

The signed data is processed afterward in two steps:

  • First, the signature is checked with the Test-PgpSignedFile command which returns Boolean: True if verification passed and False in all other cases (a signature is broken, wrong public key).
  • The second step is the extraction of the data through the ConvertFrom-PgpSignedFile command:
ConvertFrom-PgpSignedFile -Path C:\signed.pgp -Output c:\data.txt
 
$test = Test-PgpSignedFile -Path C:\data.pgp -Key c:\sender_public_key.asc
if ($test) {
  Write-Host "signature verified"
} else {
  Write-Host "signature verification failed"
}

One pass sign and encrypt and decryption

The one pass sign and encrypt is done by using our private key for signing and the public key of the recipient for encrypting. The command for signing and encrypting in one pass is ConvertTo-PgpSignedAndEncryptedFile

1
ConvertTo-PgpSignedAndEncryptedFile -Path C:\INPUT.txt -Key C:\my_private_key.asc -Password "my key password" -PublicKey c:\recipient_pub_key.asc -Output c:\encrypted.pgp

The decryption and signature verification are done in two steps. For decryption, we use the same command used for encrypted only files ConvertFrom-PgpEncryptedFile. The signature is tested with the Test-PgpSignedAndEncryptedFile:

1
2
3
4
5
6
7
8
ConvertFrom-PgpEncryptedFile -Path C:\encrypted.pgp -Key C:\my_private_key.asc -Password "my key password" -Output c:\data.txt
 
$test = Test-PgpSignedAndEncryptedFile -Path C:\encrypted.pgp -Key C:\my_private_key.asc -Password "my key password" -PublicKey c:\sender_public_key.asc
if ($test) {
  Write-Host "signature verified"
} else {
  Write-Host "signature verification failed"
}

Clear text signing and verifying

Clear text signatures are just like OpenPGP signed data but the data is visible as plain text. The commands used are ConvertTo-PgpClearSignedFile, ConvertFrom-PgpClearSignedFile and Test-PgpClearSignedFile:

1
2
3
4
5
6
7
8
9
10
ConvertTo-PgpClearSignedFile -Path C:\INPUT.txt -Key C:\my_private_key.asc -Password "my key password" -Output c:\signed.pgp
 
ConvertFrom-PgpClearSignedFile -Path C:\signed.pgp -Output c:\data.txt
 
$test = Test-PgpClearSignedFile -Path C:\data.pgp -Key c:\sender_public_key.asc
if ($test) {
  Write-Host "signature verified"
} else {
  Write-Host "signature verification failed"
}

Detached signing and verifying

Detached digital signatures reside in a separate file from the data. The command used for creating a detached signature is ConvertTo-PgpDetachedSignedFile. The signature is checked afterward with Test-PgpDetachedSignedFile.

Powershell Example:

1
2
3
4
5
6
7
8
9
10
ConvertTo-PgpDetachedSignedFile -Path C:\data.txt -Key C:\my_private_key.asc -Password "my key password" -Output c:\data.txt.sig
 
 
 
$test = Test-PgpDetachedSignedFile -Path C:\data.txt -Key c:\sender_public_key.asc -Sinature data.txt.sig
if ($test) {
  Write-Host "signature verified"
} else {
  Write-Host "signature verification failed"
}

Generating keys

Keys can also be generated and the module exposes three different commands: New-PgpKeyRsa for RSA based keys, New-PgpKeyDhDss for DH/DSS (ElGamal) keys and New-PgpKeyEcc for OpenPGP keys based on Elliptic Curves.

1
2
3
New-PgpKeyRsa -Length 2048 -Name "Richard Koosh" -Password "my key pass" -Output c:\my_key.asc
New-PgpKeyDhDss -Length 2048 -Name "Richard Koosh" -Password "my key pass" -Output c:\my_key.asc
New-PgpKeyEcc -Curve NIST-P-256 -Name "Richard Koosh" -Password "my key pass" -Output c:\my_key.asc

Passwords as SecureString

The passwords for unlocking a private key can be specified as a System.Security.SecureString with the -SecurePassword instead of the -Password parameter which is of type System.String.

The passwords for unlocking a KeyStore can be specified as a System.Security.SecureString with the -SecureKeyStorePassword instead of the -KeyStorePassword parameter which is of type System.String.

Using keys from PGP and GnuPG

On machines with existing installations of Symantec PGP command line or GnuPG, the DidiSoft PowerShell commands can utilize keys directly from the key storage of those applications. Both the key ring format of pubring/secring files and the new GnuPG .kbx file format and directory for private keys are supported.

Public keys

To use a public key from a pubring.pgp file we have to specify its location with the -Pubring parameter and the key with the -Key parameter with part of the User ID or the hexadecimal Key ID. For example:

ConvertTo-PgpEncryptedFile ... -Pubring c:\GnuPG\pubring.gpg -Key "09AC3456" ...
ConvertTo-PgpEncryptedFile ... -Pubring c:\GnuPG\pubring.gpg -Key "acm@company.com" ...
ConvertTo-PgpEncryptedFile ... -Pubring c:\GnuPG\pubring.kbx -Key "09AC3456" ...

Private keys

For utilizing a private key the -Secring parameter must point to a secring.pgp file or for the new GnuPG versions it can point to a folder with private keys:

ConvertFrom-PgpEncryptedFile ... -Secring c:\GnuPG\secring.gpg -Password "private key password" ...
ConvertFrom-PgpEncryptedFile ... -Secring c:\GnuPG\private-keys-v1.d\ -Password "private key password" ...

Getting information from PGP keys

We can obtain information from a PGP key with the Get-PgpKeyInfo command:

1
Get-PgpKeyInfo -Path c:\key.asc -Type UserId

Possible values for the -Type argument are:

  • KeyIdsRaw – an array of raw Key IDs of type System.Int64
  • MasterKeyIdRaw – master Key ID of type System.Int64
  • KeyIdRaw – same as MasterKeyIdRaw
  • KeyId – master Key ID in short hexadecimal format of type System.String
  • MasterKeyId – same as KeyId
  • KeyIdLong – master Key ID in full hexadecimal format of type System.String
  • MasterKeyIdLong – same as KeyIdLong
  • KeyIds – an array of Key IDs in short hexadecimal format of type System.String
  • KeyIdsLong – an array of the Key IDs in full hexadecimal format of type System.String
  • UserId – primary User ID of type System.String
  • PrimaryUserId – same as UserId
  • UserIds – an array of User IDs of type System.String
  • Algo – master key algorithm name of type System.String
  • Expiration – master key expiration
  • Ciphers – an array of cyphers preferences of type DidiSoft.Pgp.CypherAlgorithm ,
  • Hashes – an array of hash preferences of type DidiSoft.Pgp.HashAlgorithm ,
  • Compressions – an array of compression preferences of type DidiSoft.Pgp.CompressionAlgorithm ,
  • IsPrivateKey – System.Boolean indicating is there a private OpenPGP key in the specified key file

Getting help

Command line help for each of the provided Cmdlets is available via the Get-Help command, like:

1
Get-Help ConvertTo-PgpClearSignedFile

Also .CHM help file is available under the library folder \Help\DidiSoft.Pgp.PowerShell.chm and in the Start menu program group of the library.

Summary

This chapter summarizes the usage of DidiSoft.Pgp.PowerShell.dll which provides a ready set of Windows Powershell commands on top of DidiSoft OpenPGP Library for .NET.

The described module exposes the most common functionality of the library. In future versions additional commands will also be implemented.