DSA签名:openssl_sign(php)vs Crypt :: OpenSSL :: DSA(perl)不匹配

时间:2013-11-14 11:25:48

标签: perl openssl dsa php-openssl

目前在我的项目中,DSA签名是通过perl生成的,并通过其他服务器上的perl验证。它工作正常。

前几天我试图将一个服务从perl迁移到php,发现php生成了一些标志,perl无法验证。更重要的是,如果我生成登录控制台(使用openssl命令) - perl也表示签名无效。 所以,看起来像这样:

PHP签名< = ok =>控制台签名< =不行! => perl签名

为什么会这样?

用于签名的私钥是相同的。

Perl代码:

my $pk = Crypt::OpenSSL::DSA->read_priv_key('private.key');
print encode_base64( $pk->sign( md5($data) ) );

PHP代码:

$pk = openssl_get_privatekey('private key string');
openssl_sign(md5($data, true), $signature, $pk, OPENSSL_ALGO_DSS1));
echo base64_encode($signature);

控制台代码(验证):

openssl dsa -in private_key.pem -pubout -out dsa_public_key.pem
openssl dgst -dss1 -verify dsa_public_key.pem -signature sign.bin data.md5

完全失去了..第二天我找不到任何答案:( 你能告诉我一个挖掘的方法吗?

1 个答案:

答案 0 :(得分:2)

请注意,在您的示例中,您在签名时正在进行双重摘要:dss1(md5(message)) - 其中dss1实际上意味着sha1

所以,你创建这样的签名:

echo -n 'data you want to sign' | openssl dgst -md5 -binary | openssl dgst -dss1 -sign openssl_dsa1_pri.pem > signature.bin

您可以通过openssl comman验证它:

echo -n 'data you want to sign' | openssl dgst -md5 -binary | openssl dgst -dss1 -verify openssl_dsa1_pub.pem -signature signature.bin

使用Crypt :: OpenSSL :: DSA,您可以像这样验证它:

my $signature = read_file("signature.bin");
my $message = 'data you want to sign';
my $pub = Crypt::OpenSSL::DSA->read_pub_key('openssl_dsa1_pub.pem');
warn "Verified=", $pub->verify(sha1(md5($message)), $signature), "\n";

当然不需要双重摘要,你可以使用:

echo -n 'data you want to sign' | openssl dgst -dss1 -sign openssl_dsa1_pri.pem > signature2.bin

echo -n 'data you want to sign' | openssl dgst -dss1 -verify openssl_dsa1_pub.pem -signature signature2.bin

my $signature = read_file("signature2.bin");
my $message = 'data you want to sign';
my $pub = Crypt::OpenSSL::DSA->read_pub_key('openssl_dsa1_pub.pem');
warn "Verified=", $pub->verify(sha1($message), $signature), "\n";