in reply to Crypt fun

Your get_pubkey function better be returning a Crypt::RSA::Key::Public object. That's a public key object in the Crypt::RSA world.

Because that's the thing you're passing to Crypt::RSA, and that's what it expects. $public_key, in other words, should be an object of type Crypt::RSA::Key::Public. That's why you're getting the "Can't call method n" on $public_key error: because you're probably giving it a string or something, and the string obviously can't support method calls.

So what you should be doing is having your get_pubkey return a Crypt::RSA::Key::Public object. How do you do that? Well, you create such an object, then fill it with values. An RSA public key should have two components: n, the RSA modulus; and e, the exponent. This is used when doing public-key encryption on a message. So, in get_pubkey, you can create a public key object:

my $key = Crypt::RSA::Key::Public->new;
and then fill it the values, which you're apparently getting from *somewhere* (your base64-decoded string?):
$key->n($n); $key->e($e);
Perhaps, in your case, $n and $e are in your @fields array. I don't know, because that's specific to your code.

Then return $key from your function.

Take a look at the source of Crypt::RSA::Key for another example. The generate method generates a set of public and private keys from scratch (finding primes, deriving key attributes, etc.).

Replies are listed 'Best First'.
Re: Re: Crypt fun
by tame1 (Pilgrim) on Mar 27, 2001 at 20:10 UTC
    Thank you! This explanation is the best explanation of what I am doing wrong.
    All that I really know is that 1.) the cookie is in base64, 2) the last field of the cookie is the "security field", 3) the security field contains an RSA encoded MD5 hash of the rest of the cookie.

    So I have stripped off the last 64 bits (after decode_base64) into $encrypted, Read the keyring.public to see which public key went with the issuing server (in $field[2]) and returned that value into $public_key.

    I know I am a pain, but can you walk me through (in baby steps?) how I then initialize a 'new' Crypt key object, and then populate it with the values I have?

    I am not slow, just a 'visual' learner. If I cannot picture what's happening in my mind, I fail to get it, so a walk-through will really help.

    What does this little button do . .<Click>; "USER HAS SIGNED OFF FOR THE DAY"
      I don't know how familiar you are with RSA public key encryption, but it doesn't sound like you're *too* familiar with it. So here's how it works.

      To communicate with another party using encrypted messages, you need two keys: a public key and a private key. Say you're sending a message to someone: you have this person's public key, but only he knows his private key. That means that, if the message is intercepted, only he can decrypt the message. Make sense?

      So: the basic idea behind RSA public key encryption is that you know someone's public key, and you encrypt your message using that key. In Crypt::RSA, this would be done by using the Crypt::RSA->encrypt method, and the Key object would be the user's public key. When the other person receives your encrypted message, he decrypts it with his private key. On his end this would be done by using Crypt::RSA->decrypt, and the Key object would be his *private key*.

      That's a very important point to make, because you seem to be passing what you think is a public key to the decrypt method, which expects a private key.

      The reason this all works is because, when you generate RSA public and private keys, you first generate two very large primes, p and q. These are *private*, because from these primes you can derive any of the other key values, including the private key value. A private key object is really made up of d, the private key integer (derived from p and q); and n, the RSA modulus, which is the product of p and q.

      What does this mean? It means that you better have both n and d if you expect to decrypt a message encrypted by someone's public key. Because the actual decryption is, in a nutshell,

      M = c ^ d mod n
      where M is the plaintext message and c is the encrypted message.

      Here's another description of how the algorithm works.

      So in your case, what you're getting is the encrypted message. Right? So you need to decrypt it using a private key. If you have both d and n values, you can construct a private key like this:

      my $key = Crypt::RSA::Key::Private->new; $key->n($n); $key->d($d);
      Then use $key as the Key argument to decrypt.

      The problem in your case seems to be that you only have the public key. Granted I don't know exactly the details of your situation, but it would *seem* to me that if you don't have a private key, you'll have trouble decrypting the message. But then again, as I said, I don't know all of the details of your situation.