Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot

Crypt::OpenPGP - determining which cipher to use

by hv (Parson)
on Feb 02, 2004 at 14:58 UTC ( #325866=perlquestion: print w/replies, xml ) Need Help??

hv has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to PGP-encrypt data, by importing a standard text block:

data ...
and then encrypting with this example code:
#!/usr/bin/perl -w use Crypt::OpenPGP; use Crypt::OpenPGP::KeyRing; my($keyfile, $email) = @ARGV; my $ring = Crypt::OpenPGP::KeyRing->new(Filename => $keyfile); my $pgp = Crypt::OpenPGP->new(PubRing => $ring); my $crypt = $pgp->encrypt( Data => 'squeamish ossifrage', Recipients => [ $email ], Armour => 1, Cipher => 'CAST5', ); defined($crypt) ? print $crypt : die $pgp->errstr;

This works fine for encrypting with my colleague's key, but only after adding the Cipher => 'CAST5' - without that, his decrypt function complains of a 'bad session key'.

What I don't understand is how I can determine the appropriate cipher given the public key: I don't see anything in the Crypt::OpenPGP interface that would allow me to ask that from the KeyRing or KeyBlock objects once I've determined them.

I suspect I'm missing a fundamental concept somewhere; clues gratefully received.


Replies are listed 'Best First'.
Re: Crypt::OpenPGP - determining which cipher to use
by hardburn (Abbot) on Feb 02, 2004 at 15:12 UTC

    The best way is probably to use the Compat option. Crypt::OpenPGP should pick good defaults based on that.

    Public key crypto is quite computationally expensive, but block ciphers are usually pretty quick. Instead of encrypting the entire message with the public key, most implementations will create a one-time session key for use in a block cipher, encrypt that key at the beginning of the message using the public key, and then encrypt the rest of the message with the block cipher key. So what KeyRing/KeyBlock types you have has nothing to do with what kind of block cipher you use.

    I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
    -- Schemer

    : () { :|:& };:

    Note: All code is untested, unless otherwise stated

      Sure, I'd love to use the Compat option, but as far as I can see that just shifts the problem: now I need to determine which Compat option to select, presumably again based on information (which I don't know how to get) encoded in the public key block.


        What you use for Compat depends entirely on what program your colleague is using to decrypt. The OpenPGP standard allows for a comment in the first line, which is generally used to store information about the program that generated it, but Crypt::OpenPGP doesn't appear to save this information. It would be difficult to extract meaningful data from it, anyway.

        The best option is to get everyone on a program that can understand the same block cipher. 3DES is a good choice; it's old and slow, but it's supported by just about everyone, and it's been pounded on for 20+ years and brute force is still the most efficent known way to break it.

        I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
        -- Schemer

        : () { :|:& };:

        Note: All code is untested, unless otherwise stated

Re: Crypt::OpenPGP - determining which cipher to use
by iburrell (Chaplain) on Feb 03, 2004 at 00:21 UTC
    The public key in OpenPGP format stores lists of preferred symmetric, hash, and compression algorithms. The lists are in preference order, and any algorithm in the list isn't supported by the client.

    I don't see any easy way to get this information fron Crypt::OpenPGP interface. The module really should use these lists if available to choose the algorithms it uses when encrypting messages.

      Super, that gave me what I needed to find some relevant information. The standard is defined primarily in RFC 2440 and RFC 3156, and the relevant parts here are in RFC 2440 Preferred symmetric algorithms
         (sequence of one-octet values)
         Symmetric algorithm numbers that indicate which algorithms the key
         holder prefers to use.  The subpacket body is an ordered list of
         octets with the most preferred listed first. It is assumed that only
         algorithms listed are supported by the recipient's software.
         Algorithm numbers in section 9. This is only found on a self-
      and 9.2:
      9.2. Symmetric Key Algorithms
             ID           Algorithm
             --           ---------
             0          - Plaintext or unencrypted data
             1          - IDEA [IDEA]
             2          - Triple-DES (DES-EDE, as per spec -
                          168 bit key derived from 192)
             3          - CAST5 (128 bit key, as per RFC 2144)
             4          - Blowfish (128 bit key, 16 rounds) [BLOWFISH]
             5          - SAFER-SK128 (13 rounds) [SAFER]
             6          - Reserved for DES/SK
             7          - Reserved for AES with 128-bit key
             8          - Reserved for AES with 192-bit key
             9          - Reserved for AES with 256-bit key
             100 to 110 - Private/Experimental algorithm.
         Implementations MUST implement Triple-DES. Implementations SHOULD
         implement IDEA and CAST5.Implementations MAY implement any other

      Hopefully that should be enough for me to delve into the Crypt::OpenPGP::* innards, and eventually come up with a proposal to the author for an extension to the interface.



      [Update] second quote was truncated.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://325866]
Approved by Corion
Front-paged by broquaint
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (6)
As of 2021-01-24 00:51 GMT
Find Nodes?
    Voting Booth?