PGP general knowledge & Perl usage

Hello all,
I am working on an Instant Messenger client/server application that will be starting in Perl.  Unlike most popular IM protocol's, I want mine to be encrypted.  I seem to have trouble finding a way to encrypt data that only the server has the key to decrypt, but everyone has the key to encrypt.  After doing a little research on PGP, I found that with the public and private keys, it is possible to do what I want.
I noticed that there are some interesting features of PGP, such as Encrypting, Decrypting, Encrypting a signature, and a regular signature.
Could anybody explain these features better and a clear example of how to use them in both Linux and Windows?
Thank you in advance.
Who is Participating?
kanduraConnect With a Mentor Commented:
The OpenPGP code is more or less the same:

    use Crypt::OpenPGP;
    my $pgp = new Crypt::OpenPGP;
    my ($public, $private) = $pgp->keygen(
                                    Type => [RSA | DSA],
                                    Size => 1024,
                                    Identity => 'Your name <>',
                                    Passphrase => 'Your passphrase here',

    ### encrypt looks up the public key from the Recipients value (it should be stored in your public key ring)
    my $cyphertext = $pgp->encrypt(
            Data => 'Your secret message here',
            Recipients => '',

    ### decrypt looks up and unlocks the private key with the help of your passphrase
    my $plaintext = $pgp->decrypt(
            Data => $cyphertext,
            Passphrase => 'Your passphrase here',

The main difficulty I see (which may be moot), is that your public keyID has to be stored in the PGP key ring on the client before it can encrypt.

Yes, default RSA is insecure, which is why I used the OAEP padding extension. Here's an excerpt from the Crypt::RSA manual:

    It has been conclusively shown that textbook RSA is insecure[3,7]. Secure RSA requires that plaintext is padded in a specific manner before encryption and signing. There are four main standards for padding: PKCS #1 v1.5 encryption & signatures, and OAEP encryption & PSS signatures. Crypt::RSA implements these as four modules that provide overloaded encrypt(), decrypt(), sign() and verify() methods that add padding functionality to the basic RSA operations.
    Crypt::RSA::ES::PKCS1v15(3) implements PKCS #1 v1.5 encryption, Crypt::RSA::SS::PKCS1v15(3) implements PKCS #1 v1.5 signatures, Crypt::RSA::ES::OAEP(3) implements Optimal Asymmetric Encryption and Crypt::RSA::SS::PSS(3) Probabilistic Signatures.
    PKCS #1 v1.5 schemes are older and hence more widely deployed, but PKCS #1 v1.5 encryption has certain flaws that make it vulnerable to chosen-cyphertext attacks[9]. Even though Crypt::RSA works around these vulnerabilities, it is recommended that new applications use OAEP and PSS, both of which are provably secure[13]. In any event, Crypt::RSA::Primitives (without padding) should never be used directly.
    That said, there exists a scheme called Simple RSA[16] that provides security without padding. However, Crypt::RSA doesn't implement this scheme yet.
JustinPincarConnect With a Mentor Commented:
I would check out for a little explanation on how it works. Skip the beginning, it might be more useful for you towards the middle/end.

And btw, many IM clients now do allow for encryption, it just isn't turned on by default.
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

naschAuthor Commented:
Thank you, but I was wondering if I could get a specific explanation of what encrypt, sign, decrypt, and verify methods are and what they would be used for(examples) and what's needed.  Also, what is the purpose of the passphrase instead of just the public and private keys.
Also, is it usable in my application:
a key is offered at a public location and all data is encrypted using it
generally, it is only decryptable by the server with a seperate key
Possibly code examples for that purpose would be great.
Sorry if I am asking for a lot, normally I would research it myself and test out everything, but I am in a rush to just get my code working, and working securely.
You could use Crypt::RSA with OEAP:

Key generation:

    my $rsa = new Crypt::RSA;

    my ($public, $private) =
        $rsa->keygen (
            Identity  => 'Lord Macbeth <>',
            Size      => 1024,  
            Password  => 'A day so foul & fair',
            Verbosity => 1,
        ) or die $rsa->errstr();

    $public->write( Filename => 'public.key' );
    $private->write( Filename => 'private.key' );

Encryption and decryption:

    my $public  = new Crypt::RSA::Key::Public ( Filename => 'public.key'  );
    my $private = new Crypt::RSA::Key::Private( Filename => 'private.key' );

    my $oaep = new Crypt::RSA::ES::OAEP;

    my $ct = $oaep->encrypt( Key => $public, Message => $message ) ||
                die $oaep->errstr;

    my $pt = $oaep->decrypt( Key => $private, Cyphertext => $ct )   ||
                die $oaep->errstr;
naschAuthor Commented:
I've heard that RSA can be weak encryption(correct me if I'm wrong), I am looking for something that will last many years.
Also, I am liking the automatic signing of messages with PGP and the other features of PGP.
If I could be provided with code like the RSA example, except for with PGP, that would be great, especially the key generation part.

I got all that code to work under Linux after installing a CPAN module or two, but I can't even find the modules with PPM in Windows.  I will open a new question if that can't be solved with one or two lines.

Thank you very much for your responses so far!
naschAuthor Commented:
Thank you very much, I will be testing that code shortly. And after that, I will award the points, thank you very much to everyone here.
naschAuthor Commented:
One more thing, is it the same in PGP as it is in RSA?
    $public->write( Filename => 'public.key' );
    $private->write( Filename => 'private.key' );
If not, how can I add a public and/or private key to the proper keyrings?
I'm sorry, I have no clue how to add the keys to keyrings.
The keys are Crypt::OpenPGP::KeyBlock objects, which do have a save() method, but the manpage doesn't say how to actually put them in a key ring, or how to get the public keys to your clients.

Please see, and for all the details. To find all OpenPGP related modules, just do a search on one of those pages.

Hopefully you'll be able to gather all the information necessary for your app.
naschAuthor Commented:
I'm thinking of having the public key be given on a website and if a change is needed in the public key, I will have the server encrypt the new key with the old key and hand it out on a new connection, if the client is using a keyfile that is two keys old, then they should upgrade they're client, and the new installer will be downloaded from a site with an md5 hash to make sure nothings been modified(using a different public key, and a different connection server to get private data).
This client will take a while to develop, but I am trying to do this properly.  Hopefully you will see a new client around with a PGP encryption base.
Thank you very much,
naschAuthor Commented:
Ah, one more question if you don't mind, I can't seem to get Crypt::OpenPGP to install under windows, or for that matter, not many packages are installing under PPM.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.