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

I'm helping a friend intergrate Movable Type into his current login system. Since MT uses the TypeKey API for commenter auth, I figured I'd make a few changes to his login to behave like a TypeKey system.

Now according to Six Apart this sounds really simple. Once you validate the user, just take what MT submitted, process it, and return it to the URL specified.

So anyway my problem right now is with Crypt::DSA. I created a key with the following script:

#!/usr/bin/perl use Crypt::DSA; my $dsa = Crypt::DSA->new; my $key = $dsa->keygen(Size => 512, Verbosity => 1); print ref $key; foreach my $k (keys %{$key}) { print $k . "=" . $key->$k . " "; }
Ok no problem there, it created the key. Now in my actual script I need to use that key. I've tried a couple of ways to assign the key, but none of them work. How do I do this?
my %key; $key{"priv_key"} = "864936564936746739711078786791024560681741810216"; $key{"p"} = "103389578900933505962259092511631192256092079077336779855 +585334041474848850089585441001014183922540716749810264398731049494647 +20186311018367111795638927603"; $key{"g"} = "295468312836227549163017971559304985039133262378345815627 +315465892672058916494919915988882646491840732863667119568864913013161 +2326212886632087281832722137"; $key{"q"} = "1001831165198829652697436093010198645746872403487"; $key{"pub_key"} = "132346092772099461807044872757466388868899357571508 +126750807181863604967004471330240874757885029643259002077192969991245 +2512506924349344334420749206004502"; $sig = $dsa->sign(Message=>$sig_msg, Key => %key);
That fails with the error:
Can't locate object method "q" via package "p" (perhaps you forgot to load "p"?) at /usr/lib/perl5/site_perl/5.8.0/Crypt/DSA.pm line 45.

So maybe I don't understand how to assign the key var correctly. In the keygen script it doesn't have a % in front of it so lets try this:

my $key; $key->{"priv_key"} = "864936564936746739711078786791024560681741810216 +"; $key->{"p"} = "1033895789009335059622590925116311922560920790773367798 +555853340414748488500895854410010141839225407167498102643987310494946 +4720186311018367111795638927603"; $key->{"g"} = "2954683128362275491630179715593049850391332623783458156 +273154658926720589164949199159888826464918407328636671195688649130131 +612326212886632087281832722137"; $key->{"q"} = "1001831165198829652697436093010198645746872403487"; $key->{"pub_key"} = "1323460927720994618070448727574663888688993575715 +081267508071818636049670044713302408747578850296432590020771929699912 +452512506924349344334420749206004502"; $sig = $dsa->sign(Message=>$sig_msg, Key => $key);
Can't call method "q" on unblessed reference at /usr/lib/perl5/site_perl/5.8.0/Crypt/DSA.pm line 45.

Ok that helped so much that I'm pretty sure I'm over my head. So what am I doing wrong here?

Actually, if anyone has already implemented a typekey server, that would be really cool and more useful.

Replies are listed 'Best First'.
Re: How to Make Crypt::DSA use a your key to sign something
by zentara (Cardinal) on Feb 24, 2006 at 13:17 UTC
    Hi, looking at a post by Sisyphus on comp.lang.perl. misc, it seems that you CAN use the numeric keys, like you tried in your original post. He showed a neat trick ( which I will have to explore further) where he reblessed the key data, and it works.

    This brings up alot more possiblities where you might be able to remove the priv_key , and write it in PEM, so as to distribute the key?

    #!/usr/bin/perl use Crypt::DSA; my $dsa = Crypt::DSA->new; # my $key = $dsa->keygen(Size => 512, Verbosity => 1); # print ref $key; foreach my $k (keys %{$key}) { # print $k . "=" . $key->$k . " "; # } my %key; # Note: keys shortened for display $key{"priv_key"} = ........86791024560681741810216"; $key{"p"} = .........7985558533404147484885008958544 $key{"g"} = ........1562731546589267205891649491991 $key{"q"} = .......97436093010198645746872403487"; # $key{"pub_key"} = ......5081267508071818636049670044 # don't need pub_key for signing my $sig_msg = "xxxxxxxxxxxxxxxxxx\n" x 40; my $k = \%key; bless($k, "Crypt::DSA::Key"); $sig = $dsa->sign(Message=>$sig_msg, Key => $k);

    I'm not really a human, but I play one on earth. flash japh
Re: How to Make Crypt::DSA use a your key to sign something
by zentara (Cardinal) on Feb 23, 2006 at 19:32 UTC
    I don't have it all setup to test, but from the errors you are getting, and the perldoc for Crypt::DSA, it seems you are telling the program that your key is a hash or hashref, instead of the key. Try this:
    # change # $sig = $dsa->sign(Message=>$sig_msg, Key => $key); # to $sig = $dsa->sign(Message=>$sig_msg, Key => $key->{'p'} );

    I'm not really a human, but I play one on earth. flash japh
      Thanks but it still says...

      Can't call method "q" without a package or object reference at /usr/lib/perl5/site_perl/5.8.0/Crypt/DSA.pm line 45.

      perldoc for Crypt::DSA says about the Key in sign...

    • Key
      The Crypt::DSA::Key object with which the signature will be gener-
      ated. Should contain a private key attribute (priv_key).

      This argument is required.
    • So I think I somehow need to make $key be an object like what I had in the first script. I just don't see a way to do that right now. I'm sure it must be possible.
        Yeah, I just got all the pre-requisites installed, and see the problem in my testing....sorry if I led you off track. After a groups.google.search for the problem, it has been asked before on the newsgroups. What it seems to come down to, is that you cannot just take the Dump
        $key{"priv_key"} = "864936564936746739711078786791024560681741810216";
        and use that as a private key. The "key" must be a Crypt::DSA::Key object. From the looks of things, you need to save your key to a file, like
        $key->write( Type => 'PEM', Filename => $keyfile);
        then when you want to import that file
        $key = Crypt::DSA::Key->new(Type => 'PEM', Filename => $keyfile);
        Now whether you can read that into a scalar value, I don't know. But the PEM key should look like
        -----BEGIN DSA PRIVATE KEY----- MIH3AgEAAkEAuu/8bF0QtFaU8Eo3XzJzyuwyfIEoCvYxzcx5dGkTa7przkVGPaJp n6uEPIueBQEP21+SmfebPpkbKF98gw+MSwIVAMGFQpGtsAWNedBzQ85p0CkTuKYZ AkBLciRf48J8u/LYz2FejmaPs88sKPt/mNLLfzOUz6LO0HqjXOq6vD0WzGcek0Z6 VK9JD3r9eyclPNvsArZ7v/LaAkBxM58UjEqschS9r7Je28kCQ4eYC4lhkRq+pAot /kh86LBlohQZ6A6zgCyPiKNLT5VQ29vKW49f36XjYrIDUk21AhQdRFsMvKVp+W5C 7L7i0FLp3tYb6w== -----END DSA PRIVATE KEY-----
        and NOT the number string you originaly had. I will post an example if I can get it to work. :-)

        I'm not really a human, but I play one on earth. flash japh