EldoS | Feel safer!

Software components for data protection, secure storage and transfer

DecryptAndVerify returning null string

Also by EldoS: CallbackProcess
A component to control process creation and termination in Windows and .NET applications.
#25408
Posted: 06/23/2013 04:40:01
by Karan  (Basic support level)
Joined: 06/06/2013
Posts: 10

I have a set of EncryptAndSign() and DecryptAndVerify() methods that take the input as a string and return the encrypted/decrypted string as the output.

EncryptAndSign() works fine for my string input. But DecryptAndVerify returns a null string. I'm using MemoryStream in both encrypt and decrypt functions. Here is my piece of code:

Code

//global variable
static string _decryptedString;

string EncryptTextString(string sourceString)
        {
            
            var pgpwriter = new TElPGPWriter();

            pgpwriter.Armor = false;

            pgpwriter.ArmorHeaders.Clear();

            pgpwriter.Compress = true;

            pgpwriter.CompressionAlgorithm = 2;

            pgpwriter.CompressionLevel = 9;

            pgpwriter.EncryptingKeys = objOtherKeyRing;

            pgpwriter.SigningKeys = objSelfKeyRing;

            //use only public key for encyprtion
            pgpwriter.EncryptionType = TSBPGPEncryptionType.etPublicKey;

            pgpwriter.Passphrases.Clear();

            //password for signing via private key
            pgpwriter.Passphrases.Add("password for signing here");

            pgpwriter.OnKeyPassphrase += new SBPGPStreams.TSBPGPKeyPassphraseEvent(providePasswordForEncryption);

            //pgpwriter.Filename = sourceInfo.Name;

            pgpwriter.Filename = sourceString;

            pgpwriter.InputIsText = true;

            //TD: experiment with normal and low values
            pgpwriter.Protection = SBPGPConstants.TSBPGPProtectionType.ptHigh;

            pgpwriter.SignBufferingMethod = TSBPGPSignBufferingMethod.sbmRewind;

            //TD: experiment with aes-128 and other encryption types
            pgpwriter.SymmetricKeyAlgorithm = SBPGPConstants.Unit.SB_PGP_ALGORITHM_SK_AES128;

            //TD: experiment with other hash functions
            pgpwriter.HashAlgorithm = SBPGPConstants.Unit.SB_PGP_ALGORITHM_MD_SHA256;

            pgpwriter.Timestamp = DateTime.Now;

            //to be compatible with pgp <= 2.6
            pgpwriter.UseNewFeatures = false;
            pgpwriter.UseOldPackets = false;

            //open a stream to the input file

            MemoryStream inputStream = new MemoryStream(Encoding.Default.GetBytes(sourceString));

            MemoryStream encryptedStream = new MemoryStream();

            byte[] encryptedBytes;

          
            try
            {

                //encryt and sign entire file (count = 0)
                pgpwriter.EncryptAndSign(inputStream, encryptedStream, 0);

                //rewound the stream
                encryptedStream.Position = 0;

                encryptedBytes = new byte[encryptedStream.Length];

                int count = encryptedStream.Read(encryptedBytes, 0, encryptedBytes.Length);

                
            }


            finally
            {
                encryptedStream.Close();

                inputStream.Close();
            }

            return Encoding.Default.GetString(encryptedBytes);
        }




        void providePasswordForEncryption(object Sender, TElPGPCustomSecretKey Key, ref string Passphrase, ref bool Cancel)
        {
            Passphrase = "password for encryption here";
        }



This does not seem to be working:

Code

string DecryptTextString(string sourceString)
        {
          
            var pgpreader = new TElPGPReader();

            pgpreader.KeyPassphrase = "password for decryption here";

            pgpreader.OnCreateOutputStream += new TSBPGPCreateOutputStreamEvent(saveDecryptedData);
            pgpreader.OnKeyPassphrase += new TSBPGPKeyPassphraseEvent(providePasswordForVerfication);
            pgpreader.OnSignatures += new SBPGPStreams.TSBPGPSignaturesEvent(VerifySignatureValidity);

            pgpreader.DecryptingKeys = objOtherKeyRing;
            pgpreader.VerifyingKeys = objSelfKeyRing;

            MemoryStream inputStream = new MemoryStream(Encoding.Default.GetBytes(sourceString));


            try
            {

                pgpreader.DecryptAndVerify(inputStream, 0);

                
            }

            finally
            {
                inputStream.Close();
            }

            return _decryptedString;
        }


void saveDecryptedData(object Sender, string Filename, DateTime TimeStamp, ref Stream Stream, ref bool FreeOnExit)
        {    

            Stream = new MemoryStream();

            byte[] decryptedBytes = new byte[Stream.Length];

            Stream.Position = 0;

            Stream.Read(decryptedBytes, 0, decryptedBytes.Length);

            _decryptedString = Encoding.Default.GetString(decryptedBytes);

            FreeOnExit = true;

        }

        void providePasswordForVerfication(object Sender, TElPGPCustomSecretKey Key, ref string Passphrase, ref bool Cancel)
        {

            Passphrase = "password for decryption here";

        }


void VerifySignatureValidity(object Sender, TElPGPSignature[] Signatures, SBPGPStreams.TSBPGPSignatureValidity[] Validities)
        {

            Console.WriteLine("Inside verify signature validity event");

            if (Signatures.Length <= 0 || Validities.Length <=0)
            {
                Console.WriteLine("Inside check condition");
              
                return;
            }

            TElPGPSignature sig = Signatures[0];
            TSBPGPSignatureValidity val = Validities[0];

            Console.WriteLine(sig + Environment.NewLine + val);

            if (val == TSBPGPSignatureValidity.svValid)
            {
                Console.WriteLine("Inside valid signature condition");

                this.verificationStatus = true;
            }

          

        }




However, when i use FileStream in saveDecryptedData, it writes the decrypted string to file.

This works:

Code

void saveDecryptedData(object Sender, string Filename, DateTime TimeStamp, ref Stream Stream, ref bool FreeOnExit)
        {

            Stream = new FileStream("decrypted.txt",FileMode.Create);    

            FreeOnExit = true;

        }


How can i modify my DecryptAnVerify() method to return me the decrypted string instead of writing to a file?
#25409
Posted: 06/23/2013 08:43:51
by Eugene Mayevski (EldoS Corp.)

Your SaveDecryptedData makes no sense -- you allocate a new stream, immediately read the data from it (and there's no data there obviously) and also you set FreeOnExit to true, making the stream to be disposed when DecryptAndVerify completes.

OnCreateOutputStream is called *before* any decryption is done. The created stream is returned to the component which saves the data to it and optionally closes the stream.

In your case you need a simpler approach, shown in Samples\C#\OpenPGPBlackbox\Primitives\DecryptPassword - create a stream and assign it to pgpReader.OutputStream property before calling DecryptAndVerify. Please refer to the sample's code for details.


Sincerely yours
Eugene Mayevski
#25411
Posted: 06/23/2013 10:40:28
by Karan  (Basic support level)
Joined: 06/06/2013
Posts: 10

Quote
Eugene Mayevski wrote:
Your SaveDecryptedData makes no sense -- you allocate a new stream, immediately read the data from it (and there's no data there obviously) and also you set FreeOnExit to true, making the stream to be disposed when DecryptAndVerify completes.

OnCreateOutputStream is called *before* any decryption is done. The created stream is returned to the component which saves the data to it and optionally closes the stream.

In your case you need a simpler approach, shown in Samples\C#\OpenPGPBlackbox\Primitives\DecryptPassword - create a stream and assign it to pgpReader.OutputStream property before calling DecryptAndVerify. Please refer to the sample's code for details.



Thanks Eugene. I was able to resolve the issue.

I'm pasting my code for completeness sake and for anyone who encounters this situation in the future:


Code

        void saveDecryptedDataToString(object Sender, string Filename, DateTime TimeStamp, ref Stream Stream, ref bool FreeOnExit)
        {
            Stream = new MemoryStream();
            FreeOnExit = false;
        }


public string DecryptAndVerifyTextString(string sourceString, TElPGPKeyring decryptingKeyRing, TElPGPKeyring verificationKeyRing, string decryptingSecretKeyPassword)
        {
            //FileStream inputStream;

            var pgpreader = new TElPGPReader();

            pgpreader.KeyPassphrase = decryptingSecretKeyPassword;

            pgpreader.OnCreateOutputStream += new TSBPGPCreateOutputStreamEvent(saveDecryptedDataToString);
            pgpreader.OnKeyPassphrase += new TSBPGPKeyPassphraseEvent(providePasswordForVerfication);
            pgpreader.OnSignatures += new SBPGPStreams.TSBPGPSignaturesEvent(VerifySignatureValidity);

            pgpreader.DecryptingKeys = decryptingKeyRing;
            pgpreader.VerifyingKeys = verificationKeyRing;

            //inputStream = new FileStream(sourceFile, FileMode.Open);

            MemoryStream inputStream = new MemoryStream(Encoding.Default.GetBytes(sourceString));

            MemoryStream decryptedStream = new MemoryStream();

            pgpreader.OutputStream = decryptedStream;

            try
            {

                pgpreader.DecryptAndVerify(inputStream, 0);

                byte[] decryptedBytes = new byte[pgpreader.OutputStream.Length];

                pgpreader.OutputStream.Position = 0;

                pgpreader.OutputStream.Read(decryptedBytes, 0, decryptedBytes.Length);

                _decryptedString = Encoding.Default.GetString(decryptedBytes);

            }

            finally
            {
                inputStream.Close();

                pgpreader.OutputStream.Close();
            }

            return _decryptedString;
        }


Reply

Statistics

Topic viewed 1643 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!