OpenPGP Library for .NET News

Articles related to DidiSoft OpenPGP Library for .NET.

New features in OpenPGP for .NET 1.8.2.2

In version 1.8.2.2 of DidiSoft OpenPGP Library for .NET version you will find support for 2048 and 3076 bit DSA master signing keys, Elliptic Curve OpenPGP keys based on the Brainpool curves and some other extras.

Brainpool ECC keys

With the new version we can create an Elliptic Curve OpenPGP key just like the standard ECC keys based on NIST curves :

C# example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using System;
using DidiSoft.Pgp;
 
public class GenerateEccKeyPairDemo
{
   public void Demo()			
   {
       KeyStore ks = new KeyStore();
 
       // EC curve for this key   
       EcCurve curve = EcCurve.Brainpool256;
       // primary User Id of the key
       string userId = "Demo <demo@didisoft.com>";
       // password for the private key
       string privateKeyPassword = "changeit";
 
       ks.GenerateEccKeyPair(curve, userId, privateKeyPassword);
   }
}

VB.NET example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Imports System
Imports DidiSoft.Pgp
 
Public Class GenerateEccKeyPairDemo
   Public Sub Test()
       Dim ks As New KeyStore()
 
       '  EC curve for this key
       Dim curve As EcCurve = EcCurve.Brainpool256
       ' primary User Id of the key
       Dim userId As String = "Demo <demo@didisoft.com>"
       ' password for the private key
       Dim privateKeyPassword As String = "changeit"
 
       ks.GenerateEccKeyPair(curve, userId, privateKeyPassword)
   End Sub
End Class

Large DSA based keys

Large DH/DSS (DSA) based keys can be generated with the method KeyStore.GenerateDhDssKeyPair. Here we can specify the size of the master signing key (DSA key) and the encryption key Diffie-Hellman (DH key) separately. And overloaded version of the more general KeyStore.GenerateKeyPair has also be added for specifying separately the size of the encryption and signing keys, or the Elliptic curves respectively for ECC OpenPGP keys.

Brainpool ECC keys in PowerShell

Brainpool curves based OpenPGP keys can be created in PowerShell now too:

New-PgpKeyEcc -Curve Brainpool-512 -Name “Richard Koosh” -Password “my key pass” -Output c:\my_key.asc

What symmetric cipher was used?

Did you wondered what is the symmetric cipher used to encrypt the data in a given pgp archive? Now you can find out with the help of DidiSoft.Pgp.Inspect.PGPInspectLib:

1
2
3
4
5
6
7
8
9
10
11
FileInfo pgpFile = new FileInfo(OutputFolder + "output.pgp");
pgpFile.Delete();
pgp.EncryptFile(SmallText, PublicKey, pgpFile, true, true);
 
using (Stream dataStream = pgpFile.OpenRead())
using (Stream keyStream = PrivateKey.OpenRead())
{
	DidiSoft.Pgp.Inspect.PGPInspectLib inspect = new DidiSoft.Pgp.Inspect.PGPInspectLib();
 
	Console.WriteLine(inspect.GetEncryptionCypher(dataStream, keyStream, Password));
}

What else

Check the Release notes for all the new additions or drop us a line if you have any comments a questions?

Read more...

OpenPGP Library for .NET 1.8

We are glad to announce the release of DidiSoft OpenPGP Library for .NET version 1.8

The new version is based on BouncyCastle crypto toolkit version 1.8 and provides DLL files for the following platforms:

  • .NET Framework 2.0 – 4.6
  • Universal Windows (UWP)
  • Windows Store (WinRT)
  • Windows Phone 8.1
  • .NET Core 1.1
  • Xamarin Android and iOS
  • Compact Framework 3.5

Async support

The .NET 4.6 assemblies now support asynchronous OpenPGP cryptography methods. In order to utilize them you must use the PGPLibAsync class (subclass of DidiSoft.Pgp.PGPLib)

using DidiSoft.Pgp;
 
public class AsyncDemo 
{
  public async void MyAsyncMethod() 
  {
    PGPLibAsync pgp = new PGPLibAsync();
    await pgp.EncryptFileAsync(...);
  }
}

LDAP, SEMS and Xamarin

DidiSoft.Pgp.Net.LdapClient is now available for Xamarin too. Keys upload to Symantec Encryption Management Server (SEMS) is now possible if the connection is authenticated with a write access user account credentials and PGP Verified Directory is enabled on the SEMS server.

PowerShell additions

The PowerShell cmdlets now support keys from a KeyStore as well. The syntax is as follows:

PS C:\> ConvertTo-PgpSignedFile -Path C:\Temp\0xC4262702-pub.asc -Key DidiSoft -Password test -KeyStore C:\PGPKeys\my.keystore -KeyStorePassword test

Information for a pgp key file

A new cmdlet Get-PgpKeyInfo is available that obtains information for pgp key files. More information can be found in the PowerShell tutorial.

What’s next this year

Support for 3072 master DSA keys is on the go, additional PowerShell cmdlets, example applications for UWP, Azure and Xamarin and support for the Brainpool Elliptic curves.

Read more...

Long Hex Key ID’s in OpenPGP for .NET

Recent posts on the Internet described hacks that allowed intruders to fake Linus Torvalds OpenPGP key by providing a key that has the same short hexadecimal representation. A full Key ID is 64 bit long (8 bytes) but represented as a hexadecimal string it takes 16 characters (2 for each byte) and this was initially considered hard for typing.

"08A321B6" // short key id
"3D4761A008A321B6" // long key id

GnuPG and command line versions of PGP used all over their tutorials short key ID’s, produced by the lower 32 bits of the real Key ID. But after the recent threats this may become obsolete and probably in the future the full hexadecimal Key ID’s may become mandatory.

Support for long key ID’s

In order to address this issue today we have shipped a new version 1.7.15.5 of DidiSoft OpenPGP Library for .NET that fully supports long hexadecimal Key ID’s. Check below a short code snippet that illustrates the difference between short and link key id’s:

// C# example
KeyStore ks = KeyStore.OpenFile(@"c:\mykeys.keystore", "my keystore pass");
PGPLib pgp = new PGPLib();
// short key id
string encryptedMessage = pgp.EncryptString("Hello World!", ks, "08A321B6"); 
// long key id
string encryptedMessage2 = pgp.EncryptString("Hello World!", ks, "3D4761A008A321B6");
// VB.NET example
Dim ks As KeyStore = KeyStore.OpenFile("c:\mykeys.keystore", "my keystore pass")
Dim pgp As New PGPLib()
' short key id
Dim encryptedMessage As String = pgp.EncryptString("Hello World!", ks, "08A321B6")
' long key id
Dim encryptedMessage2 As String = pgp.EncryptString("Hello World!", ks, "3D4761A008A321B6")

Print long hexadecimal key ID’s

Both DidiSoft.Pgp.KeyStore and DidiSoft.Pgp.KeypairInformation classes provide a static method KeyIdToLongHex that converts a raw key ID of type long (Int64) into a full hexadecimal representation:

long keyId = ...
string longHexKeyId = KeyStore.KeyIdToLongHex(keyId);

Convert line endings of text files

Another recent change that was introduced is the automatic conversion of line endings of decrypted text files to the default for the current operating system, which is CrLf (/r/n) for Windows.

For example a text document encrypted on Mac will have only the new line character (\n) line endings. Decrypted on Windows the new line character will be automatically corrected. This will be done only if the encrypted file is marked internally as text. If for some reason you need to have the line endings intact, just switch the property KeepLineEndingsIntact to true like:

// C# example
PGPLib pgp = new PGPLib();
pgp.KeepLineEndingsIntact = true;
// no conversion will be made for decrypted text files

 

Read more...

OpenPGP Library for .NET 1.7.15.2 offers 2048 bit DSA master signing keys

DidiSoft OpenPGP Library for .NET version 1.7.15.2 was shipped today. It offers creation of 2048 bit DSA master signing keys in DH/DSS (ElGamal) key pairs and signing keys with non exportable (local) signatures.

2048 bit DSAmaster signing keys

By default the library will create a 1024 bit DSA master signing key when generating a DH/DSS (ElGamal) key pair. In order to force the new functionality offering a 2048 bit DSA master key a special property Force2048bitDSA of the KeyStore class must be set:

1
2
3
KeyStore ks = new KeyStore();
ks.Force2048bitDSA = true;
// now newly generated ElGamal keys will have a 2048 bit master signing key

Signing public keys with non exportable signature

If you need to sign public keys just for your own needs, then an overloaded version of the KeyStore.SignPublicKey method offers this functionality through its last parameter which indicates the signature exportability:

C# example

// ks is of type DidiSoft.Pgp.KeyStore
bool exportable = false;
ks.SignPublicKey("ceo@company.com", "my key user id", "my password", exportable);

VB.NET example

' ks is of type DidiSoft.Pgp.KeyStore
Dim exportable As Boolean = False
ks.SignPublicKey("ceo@company.com", "my key user id", "my password", exportable)

Fix in Web of Trust

When adding a new User Id to an Ultimately trusted key, the trust was lost due to a bug in the library. This has been fixed and the trust value will be preserved.

For a complete list of changes in this release, please check the release notes.

Read more...

OpenPGP Library for .NET 1.7.15 provides PowerShell commands

Today has been released version 1.7.15 of OpenPGP Library for .NET .

Windows PowerShell support

The major new thing in this release is a Powershell module with a wide range of OpenPGP related Cmdlets from encryption to creation of keys.

The commands will be available in the Powershell console right after the setup of the new version. Check the complete tutorial chapter dedicated to the usage of the Cmdlets here: www.didisoft.com/net-openpgp/examples/powershell/

Support for Camellia

In this new release the library can handle .pgp archives encrypted with the Camellia cipher (RFC 5581 – The Camellia Cipher in OpenPGP, an outside extension of the  core OpenPGP Standard RFC 4880). Although not very commonly implemented, recently more and more companies adopt the open source GnuPG software, which supports it out of the box. In order to be compatible with them in all possible scenarios we’ve decided to add decryption support for it.

DSA and RepeMD160

DSA based digital signatures require at least 160 bit hash input, so the RipeMD160 (DidiSoft.Pgp.HashAlgorithm.RIPEMD16) is a valid hash for it. We were very surprised to find out that the previous version of the library cannot handle such signatures. This has been fixed in this release.

What’s next?


In the next version we will provide a complete functionality for creation of sub keys. The speed of generating DH/DSS (ElGamal) keys will be dramatically improved using pre-computed prime numbers from RFC 3526 and support for 2048 bit DSS signing keys will be provided.

Read more...

New digital signature checking in v 1.7.12 of OpenPGP Library for .NET

Version 1.7.12 of DidiSoft OpenPGP Library for .NET completely changes the outcome of the methods that verify OpenPGP digital signatures. Fortunately the .NET framework allowed us to make this big change and still offer backward compatibility with the current code base that uses versions prior to 1.7.12.

Read below:

The problem with the old design

All methods of the library that were dealing with digital signatures : Verify, DecryptAndVerify, DetachedVerify had one big problem: the outcome was a Boolean result with meanings True = signature has been verified and False = a very fuzzy situation, could be that the signature is forged, the provided for the check public key doesn’t match or there is no signature at all:

       DidiSoft.Pgp.PGPLib pgp = new DidiSoft.Pgp.PGPLib();
       // check the signature and extract the data 
       bool validSignature = pgp.Verify...
       Console.WriteLine("Valid Signature: " + validSignature);

The new solution

As of version 1.7.12 of the library all the digital signature verification methods return a value of type DidiSoft.Pgp.SignatureCheckResult. This value has static fields that describe the four possible outcomes of a signature check:

DidiSoft.Pgp.PGPLib pgp = new DidiSoft.Pgp.PGPLib();
// check the signature and extract the data 
DidiSoft.Pgp.SignatureCheckResult signatureCheck = pgp.Verify... 
 
if (signatureCheck == SignatureCheckResult.SignatureVerified)
{
   Console.WriteLine("Signature OK");
}
else if (signatureCheck == SignatureCheckResult.SignatureBroken)
{
   Console.WriteLine("Signature of the message is either broken or forged");
}
else if (signatureCheck == SignatureCheckResult.PublicKeyNotMatching)
{
   Console.WriteLine("The provided public key doesn't match the signature");
}
else if (signatureCheck == SignatureCheckResult.NoSignatureFound)
{
   Console.WriteLine("This message is not digitally signed");
}

Backward compatibility

Having in mind that many organization have already build a solid code base around the old style of the methods, we relied on the operator overloading provided by the .NET Framework in order to provide backward compatibility. This way all the old code (except clear text signatures) will work fine with all new versions of the library. The following two lines will both compile :

DidiSoft.Pgp.PGPLib pgp = new DidiSoft.Pgp.PGPLib();
// check signature - old way
bool validSignature = pgp.Verify... 
// check signature - new way
DidiSoft.Pgp.SignatureCheckResult signatureCheck = pgp.Verify...

Clear text signatures

Unfortunately in the way that clear text signatures were verified in versions prior 1.7.12, there was an inconsistency when the provided public key doesn’t match the signature. In that case DidiSoft.Pgp.Exceptions.WrongPublicKeyException was thrown. As of version 1.7.12 there will be no exception and the resutt value will be DidiSoft.Pgp.SignatureCheckResult.PublicKeyNotMatching.

In order to migrate your code base for clear text signatures verification, you have to move the code inside the catch clause for DidiSoft.Pgp.Exceptions.WrongPublicKeyException into the check for DidiSoft.Pgp.SignatureCheckResult.PublicKeyNotMatching:

Old code for clear text signatures verification:

DidiSoft.Pgp.PGPLib pgp = new DidiSoft.Pgp.PGPLib();
// check a clear text signature
try {
  bool validClearTextSignature = pgp.Verify... 
} catch (DidiSoft.Pgp.Exceptions.WrongPublicKeyException) {
 // do something when the public key is not for this signature
}

New code for clear text signature verification

DidiSoft.Pgp.PGPLib pgp = new DidiSoft.Pgp.PGPLib();
// check a clear text signature
SignatureCheckResult signatureCheck = pgp.Verify... 
 
if (signatureCheck == SignatureCheckResult.PublicKeyNotMatching)
{
 // do something when the public key is not for this signature
}

What if we don’t migrate our code for clear text signatures? In that case when you provide a public key from different recipient for clear text signature checking, your code will continue in the place where you handle the vague false result.

Read more...

Master keys for silent additional recipients

Version 1.7.11.10 of OpenPGP Library for .NET offers a feature called master keys.

What are Master keys?

Master keys are registered on a per instance of the DidiSoft.Pgp.PGPLib class and after the registration they are used silently on each encryption and sign and encrypt operation.

Here is an example scenario for this feature:

An organization sends PGP encrypted files to a partner organization. The files are encrypted with the public key of the partner company and only the partner can decrypt it with their private key.

For audit purposes, the source organization must be able also to decrypt the files. Here master keys can help. They are registered per instance of the DidiSoft.Pgp.PGPLib class and on each call to Encrypt of SignAndEncrypt the registered master keys will also be used to encrypt silently the data files.

Please check the tutorial chapter for master keys for complete examples how to utilize this new feature.

Read more...

OpenPGP Library for .NET version 1.7.11 has been released

Today has been released version 1.7.11 of DidiSoft OpenPGP Library for .NET.

This version offers support for ADK (additional decryption keys). With the help of ADK we can encrypt silently for a list of multiple recipients by specifying explicitly only one recipient. The information for the additional recipients is contained inside the encryption key and can be modified if we have also its corresponding private key.

A tutorial chapter describing the new features can be found here: Totorial for using ADK.

 

Read more...

OpenPGP Library for .NET v1.7.10 has been released

DidiSoft OpenPGP Library for .NET version 1.7.10 has been released.

A major change in this release is the possibility to use the library in MS SQL Server ™ hosted environment.

How to Upgrade

By default the new version is installed in c:\Program Files (x86)\OpenPGP Library for .NET 1.7.10\. You will have to reference the new DLL’s in your project and redeploy it.

If you are using the LDAP connectivity you will have to also reference a new DLL : DidiSoft.Pgp.Net.LdapClient.dll.

Changes since version 1.7.9.0

Below is a short introspection of the feature updates since version 1.7.9:

 

Read more...