public static Stream PgpDecrypt(this Stream encryptedData, string armoredPrivateKey, string privateKeyPassword, Encoding armorEncoding = null) { var stream = PgpUtilities.GetDecoderStream(encryptedData); var layeredStreams = new List <Stream> { stream }; // this is to clean up/ dispose of any layered streams. var dataObjectFactory = new PgpObjectFactory(stream); var dataObject = dataObjectFactory.NextPgpObject(); Dictionary <long, PgpSecretKey> secretKeys; using (var privateKeyStream = armoredPrivateKey.Streamify(armorEncoding ?? Encoding.UTF8)) using (var decoderStream = PgpUtilities.GetDecoderStream(privateKeyStream)) { secretKeys = new PgpSecretKeyRingBundle(decoderStream). GetKeyRings().OfType <PgpSecretKeyRing>(). SelectMany(x => x.GetSecretKeys().OfType <PgpSecretKey>()). ToDictionary(key => key.KeyId, value => value); if (!secretKeys.Any()) { throw new ArgumentException("No secret keys found."); } } while (!(dataObject is PgpLiteralData) && dataObject != null) { try { var compressedData = dataObject as PgpCompressedData; var listedData = dataObject as PgpEncryptedDataList; //strip away the compression stream if (compressedData != null) { stream = compressedData.GetDataStream(); layeredStreams.Add(stream); dataObjectFactory = new PgpObjectFactory(stream); } //strip the PgpEncryptedDataList if (listedData != null) { var encryptedDataList = listedData.GetEncryptedDataObjects().OfType <PgpPublicKeyEncryptedData>().First(); var decryptionKey = secretKeys[encryptedDataList.KeyId].ExtractPrivateKey(privateKeyPassword.ToCharArray()); stream = encryptedDataList.GetDataStream(decryptionKey); layeredStreams.Add(stream); dataObjectFactory = new PgpObjectFactory(stream); } dataObject = dataObjectFactory.NextPgpObject(); } catch (Exception ex) { //Log exception here. throw new PgpException("Failed to strip encapsulating streams.", ex); } } foreach (var layeredStream in layeredStreams) { layeredStream.Close(); layeredStream.Dispose(); } if (dataObject == null) { return(null); } return((dataObject as PgpLiteralData).GetInputStream()); }