EldoS | Feel safer!

Software components for data protection, secure storage and transfer

Multi-Thread PGP

Also by EldoS: MsgConnect
Cross-platform protocol-independent communication framework for building peer-to-peer and client-server applications and middleware components.
#9345
Posted: 03/20/2009 13:19:14
by Charles Poston (Standard support level)
Joined: 06/12/2006
Posts: 15

I am using version 5.2.0.124 trying to do PGP encryption/decryption.
In a fairly tight loop I am executing roughly this code:
private TElPGPKeyring _keyring;
constructor
{
_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
SBPGPExceptions.EElPGPDecryptionStreamException:
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.



#9346
Posted: 03/20/2009 13:38:18
by Eugene Mayevski (EldoS Corp.)

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
#9366
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.
#9367
Posted: 03/23/2009 13:03:02
by Ken Ivanov (EldoS Corp.)

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.
#9368
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.
#9369
Posted: 03/23/2009 13:44:11
by Ken Ivanov (EldoS Corp.)

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.
#9370
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:

"-----BEGIN PGP ENCRYPTED MESSAGE-----

wY4DrlA/x+g880wQAgCo7flR1fY0TwASkM78kY9GH37wZIS+zvYeEs3R9qg97zhQ
Rk5RiJkrIbcrUZrjuOcztJq4hdmo3toU264yYge5Af9kN3/Gs+HqVRekq6aS5A7I
bF7SMTNAs0lUkoDuMMGbfNy0UKkv0LBkv8DFxvvHDOHaTwihPEv8ykHNBsy5mwSb
0kEBQ4XxfJWYSYyhyoUGb5WF5scfmSWJu3CXMFriIj1CXTDo8AZ2OsRnl3pZs6mB
MXiMhltoCeBlhi+1yEOoKiysTQ==
=wXvw
-----END PGP ENCRYPTED MESSAGE-----"

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?
#9371
Posted: 03/23/2009 14:40:44
by Ken Ivanov (EldoS Corp.)

Did you have a chance to check if Decrypt fails for some particular input or inputs?
#9372
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.)
#9373
Posted: 03/23/2009 16:00:50
by Ken Ivanov (EldoS Corp.)

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.

Reply

Statistics

Topic viewed 4895 times

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




|

Back to top

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

Got it!