[Botan-devel] Quick Tutorial Question

Jack Lloyd lloyd at randombit.net
Wed Oct 5 13:56:23 EDT 2005

On Wed, Oct 05, 2005 at 10:32:29AM -0700, Rachel Blackman wrote:
> I'm attempting to use Botan to do a simple encryption system that needs 
> to go into another project.  It's a great library; for a change, I have 
> seventeen ways to do everything, instead of having to puzzle out one.  
> Of course, this means I get to spend time tinkering to find what the 
> *best* way to do something is, instead! :)


> Basically, I need to be able to generate a public and private keypair, 
> encrypt a char * buffer into another char * buffer (or 
> SecureVector<byte>, either way), and decrypt the same way.  Basically, 
> encrypting/decrypting a number of small messages as separate sessions.
> At first, I thought just using PK_Encryptor/PK_Decryptor and the 
> encrypt() or decrypt() functions as in the tutorials was the way to go. 
>  I'm thinking now that pipe might be better since I realized I don't 
> necessarily have a guarantee that the block I get will be the 
> appropriate size for an encryption session.

Be careful about length issues here - a public key is only going to be able to
encrypt inputs smaller than a certain size. For example, RSA with OAEP/SHA-1
has 41 bytes of overhead, so you can only encrypt about (bitsize/8)-41 bytes at
a time (so 86 or 87 bytes for a 1024 bit modulus). If you might end up needing
to encrypt longer inputs, you should probably look into using AES for the
actual encryption with an asymmetric key used for transporting the key. You're
really not supposed to encrypt data with RSA like this at all, but as long as
you're using a good padding method and can tolerate the short length it's
reasonably safe.

As a side note, I really need to write some high level encryption filters so
people don't have to keep reinventing the wheel for this. :/

> But regardless, in my experimentation I've run into a quirk I wanted to 
> check on.  In one of my test situations, I do indeed have an 
> X509_PublicKey * as in the tutorials, nicely loaded from a file.  But 
> while attempting to dynamic_cast this X509_PublicKey * to the 
> appropriate <algo>_PublicKey * works fine, attempting to dynamic_cast 
> the PublicKey to PK_Encrypting_Key * invariably fails.  I've tried this 
> with a number of algos.  Am I missing something obvious?  (Or something 
> non-obvious that just isn't in the tutorial or explicit in the docs?)

No, I don't think you are missing anything obvious, at least it doesn't sound
like it. Here is something I just threw together

--- CUT ---
#include <botan/botan.h>
#include <botan/rsa.h>
using namespace Botan;

#include <iostream>
#include <cstdio>

int main()
   // openssl genrsa | openssl rsa -pubout > key
   const std::string key =
      "-----BEGIN PUBLIC KEY-----"
      "-----END PUBLIC KEY-----";

   try {
      LibraryInitializer init;

      // I just realized how ugly this really is... will have to think about if
      // changing the API could make this a little more elegant.
      DataSource_Memory source((const byte*)key.c_str(), key.length());
      X509_PublicKey* x509_key = X509::load_key(source);

      RSA_PublicKey* rsa_key = dynamic_cast<RSA_PublicKey*>(x509_key);

      PK_Encrypting_Key* enc_key = dynamic_cast<PK_Encrypting_Key*>(rsa_key);

      std::printf("%p %p %p\n", x509_key, rsa_key, enc_key);
   catch(std::exception& e)
      std::cout << e.what() << std::endl;
      return 1;
   return 0;
--- CUT ---

Which seems to handle the conversions correctly (in that dynamic_cast does not
return NULL). You should also be able to dynamic_cast directly from
X509_PublicKey to PK_Encrypting_Key without the intermediate cast to the
algorithm object (as long as the key type supports encryption, of course). In
Botan that would mean either an RSA or ElGamal key.


More information about the botan-devel mailing list