EldoS | Feel safer!

Software components for data protection, secure storage and transfer

Multi-Thread PGP

Also by EldoS: Solid File System
A virtual file system that offers a feature-rich storage for application documents and data with built-in compression and encryption.
Posted: 03/20/2009 13:19:14
by Charles Poston (Standard support level)
Joined: 06/12/2006
Posts: 15

I am using version trying to do PGP encryption/decryption.
In a fairly tight loop I am executing roughly this code:
private TElPGPKeyring _keyring;
_keyring = new TElPGPKeyring();
_keyring.Load( publicFile, secretFile, true );

When I use the object created by this code I get this error periodically:
SBPGPExceptions.EElPGPDecryptionStreamException: No appropriate OpenPGP secret key for decryption found
at SBPGPStreams.TElPGPDecryptingStream.ProcessBlock(Byte[] Buffer, Int32 Index, Int32 Size)
at SBPGPStreams.TElPGPDecryptingStream.OnProcessorWrite(Object Sender, Object UserData, Byte[] Buffer, Int32 Index, Int32 Size)
at SBPGPEntities.TElPGPStreamProcessor.OnEntityWrite(Object Sender, Object UserData, Byte[] Buffer, Int32 Index, Int32 Size)
at SBPGPEntities.TElPGPStreamingEntity.DoWrite(Object UserData, Byte[] Buffer, Int32 Index, Int32 Size)
at SBPGPEntities.TElPGPSymmetricallyEncrypted.LoadHeader()
at SBPGPEntities.TElPGPStreamingEntity.LoadBodyChunk(Byte[] Buffer, Boolean ALastChunk)
at SBPGPEntities.TElPGPEntity.DataAvailable()
at SBPGPEntities.TElPGPStreamingEntity.DataAvailable()
at SBPGPEntities.TElPGPStreamProcessor.DataAvailable()
at SBPGPStreams.TElPGPDecryptingStream.DataAvailable()
at SBPGP.TElPGPProcessingUnit.Write(Byte[] Buffer, Int32 Offset, Int32 Count)
at SBPGP.TElPGPReader.ProcessingUnitFinish(Object Sender)
at SBPGP.TElPGPProcessingUnit.StreamFinish(Object Sender)
at SBPGPStreams.TElPGPDearmoringStream.ProcessBlock@3(Byte[] Buf, Int32 Index, Int32 Size)
at SBPGPStreams.TElPGPDearmoringStream.ProcessBlock@3(Byte[] Buf, Int32 Index, Int32 Size)
at SBPGPStreams.TElPGPDearmoringStream.ProcessBlock(Byte[] Buffer, Int32 Index, Int32 Size)
at SBPGPStreams.TElPGPDearmoringStream.DataAvailable()
at SBPGP.TElPGPProcessingUnit.Write(Byte[] Buffer, Int32 Offset, Int32 Count)
at SBPGP.TElPGPReader.Synchronize()
at SBPGP.TElPGPReader.DecryptAndVerify(Stream ASourceStream, Int64 Count)

Note: these key file do load and work - just not every time! Especially when I hit the library from multiple threads. Is the library only single-threaded? Is it file contention? Anyone with ideas on how I might avoid this? I tried .Load retries and have still not been able to overcome this problem.

Posted: 03/20/2009 13:38:18
by Eugene Mayevski (Team)

Each instance of the component is single-threaded, but you should be able to create multiple instances and use each instance in it's own thread.

Try to check if the keys are actually loaded after the call to keyring.load(). It's really possible that the input file is blocked and the keys are not loaded.

The solution in this case would be to cache the file data in memory buffer and load the data from this buffer.

Sincerely yours
Eugene Mayevski
Posted: 03/23/2009 12:53:05
by Charles Poston (Standard support level)
Joined: 06/12/2006
Posts: 15

Doesn't the output error sequence show that the .Load is succeeding? After the .Load I am calling the Decrypt function this way:

using ( TElPGPReader reader = new TElPGPReader() ) {
reader.OutputStream = new MemoryStream();
reader.DecryptingKeys = _keyring;
reader.KeyPassphrase = passphrase;
reader.DecryptAndVerify( instream, 0 );
reader.OutputStream.Position = 0;
using ( StreamReader readstream = new StreamReader(
reader.OutputStream, Encoding.UTF7 ) ) {
string result = readstream.ReadToEnd();
return result.TrimEnd( Convert.ToChar( 0 ) );

And that is what is reporting the error.
BTW - The encrypt works fine and never errors.
Posted: 03/23/2009 13:03:02
by Ken Ivanov (Team)

How exactly do you open the input stream (instream)? It is a good idea to omit using StreamReader (if it is used in your code), as it sometimes corrupts the opened stream.

If you do not use StreamReader, please check if the issue occurs with some particular encrypted file(s) or it is random. Just try to decrypt the failed file once again and check if the same symptoms are exposed.
Posted: 03/23/2009 13:35:28
by Charles Poston (Standard support level)
Joined: 06/12/2006
Posts: 15

This is my call to the previous code (it was the body of _Decrypt function):

MemoryStream instream = new MemoryStream( Encoding.UTF8.GetBytes( input ) );
string result = _Decrypt( _adjustText( _passPhrase ), instream );

So I am opening the instream as a MemoryStream - is that correct?

I am doing basically the same for the _Encrypt and it always runs and NEVER errors.
Posted: 03/23/2009 13:44:11
by Ken Ivanov (Team)

And where the contents of the "input" string is taken from?

_Encrypt might deal with files of particular contents (e.g., containing only ASCII characters), while OpenPGP-protected files might contain any possible characters. Besides, encryption and decryption are completely different operations with their own specifics. That's why the fact that encryption works and decryption doesn't does not help here.
Posted: 03/23/2009 14:15:16
by Charles Poston (Standard support level)
Joined: 06/12/2006
Posts: 15

The input is actually a string from my database that uses the following settings:

writer.Armor = true;
writer.UseNewFeatures = true;
writer.UseOldPackets = false;
writer.Timestamp = DateTime.Now;

So I get a Unicode string that looks like this:



I want to stress that the decrypt does work - it just fails intermittently.
It seems like: .Load() gets the files successfully, calls .DecryptAndVerify which crashes before it can complete and complains that "No appropriate OpenPGP secret key for decryption found."

I am loading both the public and the secret files for the Encrypt and the Decrypt call. Is that a potential problem? Likewise I am not explicitly clearing and disposing of the keyring - is there a way to do that or is garbaage collection sufficient?
Posted: 03/23/2009 14:40:44
by Ken Ivanov (Team)

Did you have a chance to check if Decrypt fails for some particular input or inputs?
Posted: 03/23/2009 15:04:38
by Charles Poston (Standard support level)
Joined: 06/12/2006
Posts: 15

Yes, I pulled out a few that failed and tested them and they all decrypt.

I think I've actually narrowed the problem down to the SQL Server version - it works perfectly with service pack 3 - intermittently fails with earlier versions. Just suppose that when the keyring is ready to be used by the decryption and the memory containing the keys is corrupted - the error reported is what would be thrown, correct?

(I think the SecureBlackbox is working fine - thanks for your attention.)
Posted: 03/23/2009 16:00:50
by Ken Ivanov (Team)

It depends on how exactly the memory containing the keys was corrupted, but in certain cases the answer is yes. This error may be also returned for corrupted documents if they were encrypted using older encryption mode, but, as you are enabling the UseNewFeatures property, this is not the case.
Also by EldoS: BizCrypto
Components for BizTalk® and SQL Server® Integration Services that let you securely store and transfer information in your business automation solutions.



Topic viewed 5850 times

Number of guests: 2, registered members: 0, in total hidden: 0


Back to top

As of July 15, 2016 EldoS business operates as a division of /n software, inc. For more information, please read the announcement.

Got it!