EldoS | Feel safer!

Software components for data protection, secure storage and transfer

No suitable OpenPGP public key for encryption found

Also by EldoS: CallbackDisk
Create virtual disks backed by memory or custom location, expose disk images as disks and more.
#25206
Posted: 06/06/2013 13:02:31
by Karan  (Basic support level)
Joined: 06/06/2013
Posts: 10

I'm relatively new to Secure Black Box. I'm using Version 10.0.233 along with Visual Studio 2010 (.net 4.0) on Windows 7 x64 SP1.

After basic key generation, i'm trying to encrypt & sign/decrypt & verify files using PGP.

I get an exception stating "No suitable OpenPGP public key for encryption found". I've set both encryptingkeys and signingkeys.


Please find my code below:

Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SBPGP;
using SBPGPKeys;
using System.IO;

namespace ConsoleApplication2
{
    class Program
    {
        TElPGPKeyring objKeyRing;
        TElPGPKeyring objOtherKeyRing;

        TElPGPSecretKey objSelfSecretKey;
        TElPGPPublicKey objOtherPublicKey;

        Program()
        {
            //create a key ring
            objKeyRing = new TElPGPKeyring();

            objOtherKeyRing = new TElPGPKeyring();

            //create a private-public key pair object
            objSelfSecretKey = new TElPGPSecretKey();

            objOtherPublicKey = new TElPGPPublicKey();

            //i pre-generated this public key (to be used as the recipient's public key)
            objOtherPublicKey.LoadFromFile("other-public key.txt");

        }

        void GenerateAndSaveKeys(string password, int keySize, string userName)
        {
            //Generate a secret-public key pair within the object with the given password.
            objSelfSecretKey.Generate(password, keySize, SBPGPConstants.Unit.SB_PGP_ALGORITHM_PK_DSA, userName, false, 0);
            
            //add self secret-public key pair and other's public key to key ring
            objKeyRing.AddSecretKey(objSelfSecretKey);

            //add other's public key for encryption to the key ring
            objOtherKeyRing.AddPublicKey(objOtherPublicKey);

            objSelfSecretKey.SaveToFile(userName + "-private key.pgp", true);
            objSelfSecretKey.PublicKey.SaveToFile(userName + "-public key.pgp", true);

        }

        void EncryptText(string sourceFile, string destFile)
        {
            FileStream inputStream, encryptedStream;
            
            FileInfo sourceInfo = new FileInfo(sourceFile);

            var pgpwriter = new TElPGPWriter();

            pgpwriter.Armor = false;

            pgpwriter.ArmorHeaders.Clear();

            pgpwriter.Compress = false;
          
           //use the recipient's public key to encrypt
            pgpwriter.EncryptingKeys = objOtherKeyRing;

           //use self key to sign the encrypted file
            pgpwriter.SigningKeys = objKeyRing;

            //use only public key for encyprtion
            pgpwriter.EncryptionType = TSBPGPEncryptionType.etPublicKey;
            pgpwriter.Passphrases.Clear();

            pgpwriter.Filename = sourceInfo.Name;

            pgpwriter.InputIsText = true;

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


            pgpwriter.SignBufferingMethod = TSBPGPSignBufferingMethod.sbmRewind;

          
            pgpwriter.SymmetricKeyAlgorithm = SBPGPConstants.Unit.SB_PGP_ALGORITHM_SK_AES256;

          
            pgpwriter.HashAlgorithm = SBPGPConstants.Unit.SB_PGP_ALGORITHM_MD_SHA512;

            pgpwriter.Timestamp = DateTime.Now;

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

            //open a stream to the input file
            inputStream = new FileStream(sourceFile, FileMode.Open);

            encryptedStream = new FileStream(destFile, FileMode.Create);

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

            encryptedStream.Close();

            inputStream.Close();

        }



        static void Main(string[] args)
        {
           //XXXXXXXXX = my license key
           SBUtils.Unit.SetLicenseKey("XXXXXXXXX");
            
            var obj = new Program();

            obj.GenerateAndSaveKeys("password", 1024, "karan");

            obj.EncryptText("test.txt","encrypted.txt");


        }
    }
}


I've also tried running the PGPFiles sample code and i receive the same exception.

I tried debugging the program and i can see that both self and other key rings are loaded with keys (self keyring is loaded with secret key and it's corresponding public key and other key ring is loaded with recipient's public key)

Any advice would be appreciated. Thanks in advance.
#25207
Posted: 06/06/2013 13:19:42
by Eugene Mayevski (EldoS Corp.)

Most likely your public keyring contains DSA keys without subkeys. DSA algorithm can not be used for encryption but only for signing. Usually if the main key is DSA, then RSA or Elgamal keys are generated and kept as a subkey of the main key. These subkeys are used for encrypting data.


Sincerely yours
Eugene Mayevski
#25208
Posted: 06/06/2013 13:24:33
by Mykola Olshevsky (Basic support level)
Joined: 07/07/2005
Posts: 450

Eugene is right - your method GenerateAndSaveKeys generates DSA-only key, which can be used for signing. If you need to use DSA and want to encrypt data, you should generate DSA key with ElGamal subkey. See our PGPKeysDemo how to properly generate such keys.
#25222
Posted: 06/07/2013 15:11:08
by Karan  (Basic support level)
Joined: 06/06/2013
Posts: 10

Quote
Eugene
Quote
Mykola
Thanks for the quick reply.

I've modified my code as shown below. (now using RSA based keys)

I still get an error stating "Signing failed (secret key mismatch/passphrase not provided?)" on the line pgpwriter.EncryptAndSign(inputStream, encryptedStream, 0);. I have added the passphrase for the secret key used for signing in the code:

Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SBPGP;
using SBPGPKeys;
using System.IO;

namespace ConsoleApplication2
{
    class Program
    {
        TElPGPKeyring objKeyRing;
        TElPGPKeyring objOtherKeyRing;
        TElPGPSecretKey objSelfSecretKey;
        TElPGPPublicKey objSelfPublicKey;
        TElPGPPublicKey objOtherPublicKey;

        
        Program()
        {
            //create a key ring
            objKeyRing = new TElPGPKeyring();
            objOtherKeyRing = new TElPGPKeyring();

            //create a private-public key pair object (called as secret-public key pair)
            objSelfSecretKey = new TElPGPSecretKey();
            objSelfPublicKey = new TElPGPPublicKey();

            //the pgp public/private keys are generated in advance using the InitialGenerateAndSaveKeys() method

            objSelfSecretKey.LoadFromFile("karan-private key.pgp");
            objSelfPublicKey.LoadFromFile("karan-public key.pgp");

            objOtherPublicKey = new TElPGPPublicKey();
            objOtherPublicKey.LoadFromFile("other-public key.pgp");

            objKeyRing.AddSecretKey(objSelfSecretKey);
            objKeyRing.AddPublicKey(objSelfPublicKey);

            objOtherKeyRing.AddPublicKey(objOtherPublicKey);

        }
        
        //method is used to generate keys (when keys are generated, no other method is invoked except this one)
        void InitialGenerateAndSaveKeys(string password, int keySize, string userName)
        {
            objSelfSecretKey = new TElPGPSecretKey();

            //Generate a secret-public key pair within the object with the given password. (does not expire)
            //algorithm = DSA (algorithm number = 17)
            objSelfSecretKey.Generate(password, keySize, SBPGPConstants.Unit.SB_PGP_ALGORITHM_PK_RSA, userName, false, 0);
            
            //add self secret-public key pair and other's public key to key ring
            //objKeyRing.AddSecretKey(objSelfSecretKey);

            //add other's public key for encryption to the key ring
            //objOtherKeyRing.AddPublicKey(objOtherPublicKey);

            objSelfSecretKey.SaveToFile(userName + "-private key.pgp", true);
            objSelfSecretKey.PublicKey.SaveToFile(userName + "-public key.pgp", true);

        }

        void EncryptText(string sourceFile, string destFile)
        {
            FileStream inputStream, encryptedStream;
            
            FileInfo sourceInfo = new FileInfo(sourceFile);

            var pgpwriter = new TElPGPWriter();

            pgpwriter.Armor = false;

            pgpwriter.ArmorHeaders.Clear();

            pgpwriter.Compress = false;

            pgpwriter.EncryptingKeys = objOtherKeyRing;

            pgpwriter.SigningKeys = objKeyRing;

            //use only public key for encyprtion
            pgpwriter.EncryptionType = TSBPGPEncryptionType.etPublicKey;
            
            pgpwriter.Passphrases.Add("added my password for secret key here");

            pgpwriter.Filename = sourceInfo.Name;

            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_AES256;

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

            pgpwriter.Timestamp = DateTime.Now;

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

            //open a stream to the input file
            inputStream = new FileStream(sourceFile, FileMode.Open);

            encryptedStream = new FileStream(destFile, FileMode.Create);

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

            encryptedStream.Close();

            inputStream.Close();

        }



        static void Main(string[] args)
        {
            SBUtils.Unit.SetLicenseKey("XXXXXXXXX");
            
            var obj = new Program();

            obj.EncryptText("test.txt", "encrypted.txt");

        }
    }
}


What might be wrong in this case?
#25225
Posted: 06/07/2013 17:47:37
by Andy Kim (Basic support level)
Joined: 06/06/2013
Posts: 5

You set the encryption passphrase here:

Code
pgpwriter.Passphrases.Add("added my password for secret key here")


You need to set the KeyPassPhrase (password you need to sign with you keypassphrase.

I think there are a couple of different ways to do this:
1)Search forums for "OnKeyPassPhrase" event
2)Set it directly by something like: objSelfSecretKey.AddPassPhrase(0) = yourpassphrase.

The experts on here know better, but hope that helps.
#25228
Posted: 06/07/2013 23:04:10
by Karan  (Basic support level)
Joined: 06/06/2013
Posts: 10

Quote
Andy Kim wrote:
You set the encryption passphrase here:

Codepgpwriter.Passphrases.Add("added my password for secret key here")

You need to set the KeyPassPhrase (password you need to sign with you keypassphrase.

I think there are a couple of different ways to do this:
1)Search forums for "OnKeyPassPhrase" event
2)Set it directly by something like: objSelfSecretKey.AddPassPhrase(0) = yourpassphrase.

The experts on here know better, but hope that helps.



I was not able to find AddPassPhrase(index) as a property or method of objSelfSecretKey (i.e an object of class TElPGPSecretKey).

It does appear in the list shown by intelli-sense in visual studio.

I tried calling pgpwriter.Encrypt() instead of EncryptAndSign() and it worked fine. So i've pinpointed the problem to be related to signing.

PS: I tried running the sample code PGPFilesDemo with my RSA keys and it worked (with signing) when i provided the same passphrase as i passed in the function pgpwriter.Passphrases.Add("added my password for secret key here"). Am i missing something?
#25229
Posted: 06/08/2013 07:35:05
by Karan  (Basic support level)
Joined: 06/06/2013
Posts: 10

Quote
Andy Kim wrote:
You set the encryption passphrase here:

Codepgpwriter.Passphrases.Add("added my password for secret key here")

You need to set the KeyPassPhrase (password you need to sign with you keypassphrase.

I think there are a couple of different ways to do this:
1)Search forums for "OnKeyPassPhrase" event
2)Set it directly by something like: objSelfSecretKey.AddPassPhrase(0) = yourpassphrase.

The experts on here know better, but hope that helps.



Finally, i tried OnKeyPassPhrase event and it worked. Thanks a lot Andy.

For completeness sake, i'm posting the code that got it working:

Code

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

        void providePasswordForEncryption(object Sender, TElPGPCustomSecretKey Key, ref string Passphrase, ref bool Cancel)
        {
            Passphrase = "added my password for secret key here";
        }
Also by EldoS: Callback File System
Create virtual file systems and disks, expose and manage remote data as if they were files on the local disk.

Reply

Statistics

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