singpolyma / openpgp-php

OpenPGP.php is a pure-PHP implementation of the OpenPGP Message Format (RFC 4880).
http://singpolyma.github.io/openpgp-php/
The Unlicense
180 stars 69 forks source link

getting the structure output when calling sign() #25

Closed DanielRuf closed 8 years ago

DanielRuf commented 8 years ago

I get object(OpenPGP_SecretKeyPacket)#15 (15) { ...output when I sign something using OpenPGP_Crypt_RSA->sign(), but why?

fabacab commented 8 years ago

Confirmed, I think? With this code:

<?php

require_once dirname(__FILE__).'/../vendor/autoload.php';
require_once dirname(__FILE__).'/../lib/openpgp.php';
require_once dirname(__FILE__).'/../lib/openpgp_crypt_rsa.php';

$rsa = new \phpseclib\Crypt\RSA();
$k = $rsa->createKey(512);
$rsa->loadKey($k['privatekey']);

$nkey = new OpenPGP_SecretKeyPacket(array(
   'n' => $rsa->modulus->toBytes(),
   'e' => $rsa->publicExponent->toBytes(),
   'd' => $rsa->exponent->toBytes(),
   'p' => $rsa->primes[1]->toBytes(),
   'q' => $rsa->primes[2]->toBytes(),
   'u' => $rsa->coefficients[2]->toBytes()
));

var_dump($nkey);

I get this output:

$ php examples/keygen.php 
object(OpenPGP_SecretKeyPacket)#15 (15) {
  ["s2k_useage"]=>
  NULL
  ["s2k"]=>
  NULL
  ["symmetric_algorithm"]=>
  NULL
  ["private_hash"]=>
  NULL
  ["encrypted_data"]=>
  NULL
  ["version"]=>
  int(4)
  ["timestamp"]=>
  int(1456318753)
  ["algorithm"]=>
  int(1)

(Output snipped for length.)

fabacab commented 8 years ago

That's not what happens for me. To be perfectly clear, the full example I'm using (unchanged from the cloned repository except for adding Composer's autoload.php and using the full namespace to \phpseclib\Crypt\RSA() instead of the Crypt_RSA alias, and without the earlier var_dump as you asked for) is this code:

<?php

require_once dirname(__FILE__).'/../vendor/autoload.php';
require_once dirname(__FILE__).'/../lib/openpgp.php';
require_once dirname(__FILE__).'/../lib/openpgp_crypt_rsa.php';

$rsa = new \phpseclib\Crypt\RSA();
$k = $rsa->createKey(512);
$rsa->loadKey($k['privatekey']);

$nkey = new OpenPGP_SecretKeyPacket(array(
   'n' => $rsa->modulus->toBytes(),
   'e' => $rsa->publicExponent->toBytes(),
   'd' => $rsa->exponent->toBytes(),
   'p' => $rsa->primes[1]->toBytes(),
   'q' => $rsa->primes[2]->toBytes(),
   'u' => $rsa->coefficients[2]->toBytes()
));

$uid = new OpenPGP_UserIDPacket('Test <test@example.com>');

$wkey = new OpenPGP_Crypt_RSA($nkey);
$m = $wkey->sign_key_userid(array($nkey, $uid));

// Serialize private key
print $m->to_bytes();

// Serialize public key message
$pubm = clone($m);
$pubm[0] = new OpenPGP_PublicKeyPacket($pubm[0]);

$public_bytes = $pubm->to_bytes();

And when I run that, I get this (expected?) output:

$ php examples/keygen.php 
??^1?v?(????/g??d??@a????|c???{????:M?ZZ?d??G2??cN`?qH?b??F?(z????????h??KS????g2??ov??n??k?޷K???1x??q???+?kٙw?L??d??&0l??|_'?}o?z+?͂_?ҮX]??S(??ͩT
             ??Test <test@example.com>?? ?Vͪ?? ?!??? ??2??2? ???Y?"???s1#~bN?%??yGBb????'CH?v?1\IV?pI?6|?kE̦L@Oы??g 
DanielRuf commented 8 years ago

@meitar Wait, I still get the results, even using this code:

include 'vendor/autoload.php';
require_once dirname(__FILE__).'/lib/openpgp.php';
require_once dirname(__FILE__).'/lib/openpgp_crypt_rsa.php';
/* Parse secret key from STDIN, the key must not be password protected */
//$rsa = new Crypt_RSA();

$key=getKey("
-----BEGIN PGP PRIVATE KEY BLOCK-----

*snip*

-----END PGP PRIVATE KEY BLOCK-----
");

$signer = new OpenPGP_Crypt_RSA($key[0]);
$m = $signer->sign("test");
$packets = $m->signatures()[0];
$clearsign = "-----BEGIN PGP SIGNED MESSAGE-----\nHash: SHA256\n\n";
$clearsign .= preg_replace("/^-/", "- -",  $packets[0]->data)."\n";
// print $clearsign.apply_filters('openpgp_enarmor', $packets[1][0]->to_bytes(), 'PGP SIGNATURE');

function getKey ($key, $ascii = true) {
        if ($ascii) {
            preg_match('/-----BEGIN ([A-Za-z ]+)-----/', $key, $matches);
            $marker = (empty($matches[1])) ? 'MESSAGE' : $matches[1];
            $key = OpenPGP::unarmor($key, $marker);
        }
        $openpgp_msg = OpenPGP_Message::parse($key);
        return (is_null($openpgp_msg)) ? false : $openpgp_msg;
    }

But why? =(

fabacab commented 8 years ago

I still can't reproduce that. There is no output on that code for me. When I call OpenPGP_Crypt_RSA::sign() I get a result returned ($m = $signer->sign("test"); var_dump($m);) like the following, but otherwise no printed output:

object(OpenPGP_Message)#21 (2) {
  ["uri"]=>
  NULL
  ["packets"]=>
  array(2) {
    [0]=>
    object(OpenPGP_SignaturePacket)#17 (11) {
      ["version"]=>
      int(4)
      ["signature_type"]=>
      int(0)
      ["hash_algorithm"]=>
      int(8)
      ["key_algorithm"]=>
      int(1)
      ["hashed_subpackets"]=>
      array(2) {
        [0]=>
        object(OpenPGP_SignaturePacket_SignatureCreationTimePacket)#19 (3) {
          ["tag"]=>
          int(2)
          ["size"]=>
          NULL
          ["data"]=>
          int(1456320408)
        }
        [1]=>
        object(OpenPGP_SignaturePacket_IssuerPacket)#20 (3) {
          ["tag"]=>
          int(16)
          ["size"]=>
          NULL
          ["data"]=>
          string(16) "A82A452E866F5565"
        }
      }
      ["unhashed_subpackets"]=>
      NULL
      ["hash_head"]=>
      int(20137)
      ["trailer"]=>
      string(36) ?Vͯ?? ?*E.?oUe?"
      ["tag"]=>
      int(2)
      ["size"]=>
      NULL
      ["data"]=>
      array(1) {
        [0]=>
7??_W?-??ߺ?\7e?&b???L?ɽ͇8?j΍?,&܊?M??{z*??<?"??W9l?eŒ@?F?????wLt)?XqS&??V0?v?<*^?B\?6???;:U?àD՝l??t?1??]?:
fQ??؅?w+ܴ?%?#o"                                                                                  ????f}?Ϟ֢?O
      }
    }
    [1]=>
    object(OpenPGP_LiteralDataPacket)#10 (6) {
      ["format"]=>
      string(1) "b"
      ["filename"]=>
      string(4) "data"
      ["timestamp"]=>
      int(1456320408)
      ["tag"]=>
      int(11)
      ["size"]=>
      NULL
      ["data"]=>
      string(4) "test"
    }
  }
}
DanielRuf commented 8 years ago

Weird.Running the code under XAMPP with PHP 5.6. Why is the returned code printed to the output like print / var_dump? Hm. @singpolyma, any idea? Also used the example code directly.

<?php
require 'vendor/autoload.php';
require_once dirname(__FILE__).'/lib/openpgp.php';
require_once dirname(__FILE__).'/lib/openpgp_crypt_rsa.php';
$rsa = new \phpseclib\Crypt\RSA();
$k = $rsa->createKey(512);
$rsa->loadKey($k['privatekey']);
$nkey = new OpenPGP_SecretKeyPacket(array(
   'n' => $rsa->modulus->toBytes(),
   'e' => $rsa->publicExponent->toBytes(),
   'd' => $rsa->exponent->toBytes(),
   'p' => $rsa->primes[1]->toBytes(),
   'q' => $rsa->primes[2]->toBytes(),
   'u' => $rsa->coefficients[2]->toBytes()
));
$uid = new OpenPGP_UserIDPacket('Test <test@example.com>');
$wkey = new OpenPGP_Crypt_RSA($nkey);
$m = $wkey->sign_key_userid(array($nkey, $uid));
// Serialize private key
print $m->to_bytes();
// Serialize public key message
$pubm = clone($m);
$pubm[0] = new OpenPGP_PublicKeyPacket($pubm[0]);
$public_bytes = $pubm->to_bytes();
singpolyma commented 8 years ago

maybe a weird XAMPP-ism? Code looks reasonable to me

DanielRuf commented 8 years ago

Hm, ok. But getting the same result even with Bitnami WAMP Stack and cleared cache. Very weird.

singpolyma commented 8 years ago

Does not reproduce on my system (I was running the clearsign example just now and it worked as expected)

DanielRuf commented 8 years ago

Ok. Will check the system, there is definitely something causing problems on a higher level.