是否可以在 perl 中使用 SSH 私钥对我的数据进行签名? [英] Is it possible to sign my data using SSH private key in perl?

查看:32
本文介绍了是否可以在 perl 中使用 SSH 私钥对我的数据进行签名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 perl 新手,所以这可能是非常基本的,但我找不到解决这个问题的方法.我正在尝试使用我的 ssh 私钥(id_rsa) 对必须通过 https 连接发送的数据进行签名.我无法使用 perl 做到这一点,而且我已经使用了好几天了.请有人告诉我一种可能的方法.如果需要更多信息,请询问我.提前致谢

I am new to perl so this might be very basic, but i am finding no way around this problem. I am trying to sign my data which has to be send over https connection using my ssh private key(id_rsa). I am not able to do so using perl and i am at it for days. Please someone show me a possible way to do so. If any more info is needed please ask me. Thanks in advance

我问的代码是

#!/usr/bin/perl
use File::Slurp   qw(read_file);
use Crypt::OpenSSL::RSA;
use MIME::Base64 qw( decode_base64 encode_base64 );

my $keystring = read_file( 'id_rsa' );
my $privatekey = Crypt::OpenSSL::RSA->new_private_key($keystring);
$privatekey->use_pkcs1_padding();
my $datatosign = "hello";
my $signature = $privatekey->sign($datatosign);
my $base64 = encode_base64($signature);
print "$base64"; 

运行时出现的错误是 RSA.xs:178: OpenSSL error: unsupported encryption at test.pl line 7.

The error coming on running it is RSA.xs:178: OpenSSL error: unsupported encryption at test.pl line 7.

注意:正如评论中所讨论的,我使用的是受密码保护的 id_rsa.

NOTE: As discussed in the comments, I am using a passphrase protected id_rsa.

推荐答案

所以,省略了 perl,直接用 openssl 来做这个

So, leaving out the perl, and just doing this by hand with openssl

ssh-keygen -t rsa -f test_id

openssl rsa -in test_id -check
  RSA key ok

所以我们确实在那里有一个有效"的 RSA 私钥,我们应该能够将其用于加密.

So we do have a 'valid' RSA private key there, which we should be able to use for encrpyting.

但是如果您使用 openssl 生成密钥对

However if you use openssl to generate a key pair

openssl genrsa -out openssl_gen_rsa
openssl rsa -in openssl_gen_rsa -pubout -out openssl_gen_rsa.out 

看起来你需要的命令是:

Looks like the command you need is:

openssl rsautl -inkey test_id  -in test_file.txt -encrypt -out test_file.enc

(使用私钥加密,因此您可以使用公钥解密 - 这实际上与签名非常相似 - 通常您不会这样做).

(That encrypts with the private key, so you'd decrypt with the public key - that's actually pretty similar to signing - normally you wouldn't do this).

问题是 - 如果您比较生成的 -public- 密钥,它们不匹配.test_id.pub 看起来像(是的,这是真的,不,我只是将它用于测试!)

The problem is - if you compare your generated -public- keys they don't match. test_id.pub looks like (Yes, this is the real one, and no, I did only use it for testing!)

<代码> SSH-RSA AAAAB3NzaC1yc2EAAAADAQABAAABAQDKfjRD + Gb5EE + SgOy7eoT0siQaAqfSY7KI2wkdrdygnJ + CCW/uMCtCVPhpz00u3EW2Gz1WI DteLKppjvUem1lKb8Tt2EWBQGyFOYKp44r3AJZgTcxLeDdqSUoiPsjWf1aUqy2Z1fBgtG + QOa7bpA8km6CbsORYX/TVg4B6vvdkkH K8WcmzBBF3rGsTCM3VXPp56bPoMCbwCsXvIjejmq + JdGHyxUmCxe1PrPyvmoYX3OUqpFBYIjeLWGDI9EXS6jA/r7viIAxdllvulPg IJ + 4mdYzKN + T1ME0X0c + ZdFTMdeUnB9/TZmJr1j8Q/4SQm + 3J9CiwtVXKxdkDsDObkcDp根@树莓派

我生成的密钥文件如下所示:

Where my generated key file looks like:

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDG8i33AuEp1wqbJgkEsnOmQim3
QT76B/oxsVGfJEDX3h4A6CD+ypBbfhhIn0GlfHanYvcGlpOJIlk3fzspbZNeoPJS
T4a0zQ0z8uJkugl8utyl9WR4tpgBRmzXZ42T/f4QSNqjDxUidRp5zPnXs9aRDtWb
XptswiGL3eVHMpbSnwIDAQAB
-----END PUBLIC KEY-----

我可以使用我生成的对(使用公钥加密,使用私钥解密):

I can use my generated pair (encrypting using public key, decrypting using private):

openssl rsautl -inkey openssl_gen_rsa.out -pubin  -in test_file.txt -encrypt -out test_file.enc2
openssl rsautl -inkey openssl_gen_rsa -in test_file.enc2 -decrypt

这有效.

因此,如果我们通过 openssl 运行您的 ssh 私钥:

So if we run your ssh private key through openssl:

openssl rsa -in test_id -pubout -out test_id.openssl.pub

我们得到:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyn40Q/hm+RBPkoDsu3qE
9LIkGgKn0mOyiNsJHa3coJyfnHFv7jArQlT4ac9NLtxFths9ViA7XiyqaY71HptZ
Sm/E7dhFgUBshTmCqeOK9wCWYE3MS3g3aklKIj7I1n9WlKstmdXwYLRvkDmu26QP
JJugm7DkWF/01YOAer73ZJByvFnJswQRd6xrEwjN1Vz6eemz6DAm8ArF7yI3o5qv
iXRh8sVJgsXtT6z8r5qGF9zlKqRQWCI3i1hgyPRF0uowP6+74iAMXZZb7pT4CCfu
JnWMyjfk9TBNF9HPmXRUzHXlJwff02Zia9Y/EP+EkJvtyfQosLVVysXZA7Azm5HA
6QIDAQAB
-----END PUBLIC KEY-----

这甚至不是与 id_rsa.pub 文件远程相似的编码 - 因此我想为什么你会遇到这个问题.

Which isn't even a remotely similar encoding to the id_rsa.pub file - and I think therefore why you have this problem.

 openssl rsautl -inkey test_id.openssl.pub -pubin  -in test_file.txt -encrypt -out test_file.openssl.pub.enc

现在可以使用了,您可以使用您的 test_id 私钥对其进行解密:

Now works, and you can decrypt it using your test_id private key:

openssl rsautl -inkey test_id -in test_file.openssl.pub.enc -decrypt

所以是的 - 由于某种原因,ssh-keygen 生成的公钥与 openssl 期望的格式不同,所以它不会工作.

So yes - for some reason the public key generated by ssh-keygen isn't the same format as openssl is expecting, so it's not going to work.

无论如何,回到你最初的例子——使用私钥生成签名:

Anyway, back to your original example - using the private key to generate a signature:

openssl rsautl -sign -inkey test_id -in test_file.txt -out test_file.sig
openssl rsautl -verify -in test_file.sig -inkey test_id.openssl.pub -pubin

但是验证步骤不会使用生成的 ssh 密钥工作.

But the verify step won't work using the generated ssh key.

那么这是否回答了您关于它是否可能的问题?恐怕我不知道 ssh 公钥与普通" rsa 公钥有何不同.

So does this answer your question as to whether it's possible? I'm afraid I don't know how the ssh public key differs from a 'normal' rsa public key.

我怀疑您的代码因此甚至不需要那么复杂 - 我认为您不需要 pkcs 填充您的密钥文件.

I suspect your code therefore doesn't even need to be as complicated as it - I don't think you need to pkcs pad your key file.

例如

#!/usr/bin/perl
use strict;
use warnings;
use File::Slurp   qw(read_file);
use Crypt::OpenSSL::RSA;
use MIME::Base64 qw( decode_base64 encode_base64 );

my $keystring = read_file ('test_id');
my $privatekey = Crypt::OpenSSL::RSA->new_private_key($keystring);
my $datatosign = "hello";
my $signature = $privatekey->sign($datatosign);
my $base64 = encode_base64($signature);
print "Signature:\n";
print "$base64";

my $public_key_text = $privatekey-> get_public_key_string();
print "Public Key:\n";
print $public_key_text;

my $rsa_pub = Crypt::OpenSSL::RSA->new_public_key ( $public_key_text );
print "Signed correctly\n" if ($rsa_pub->verify($datatosign, decode_base64($base64)));

这似乎有效.(注意缺少 pkcs 填充线).

This seems to work. (note lack of pkcs padding line).

来自评论:

如果您的 id_rsa 设置了密码,您将获得如下信息:

If your id_rsa has a passphrase set you'll have something like this:

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,B44716076DD8B7D2B5E909BB8F70B48B

您可以再次使用 openssl 手动解密:

You can decrypt this by hand using openssl again:

openssl rsa -in test_id.enc
Enter pass phrase for test_id.enc:

或者:

openssl rsa -in test_id.enc -passin pass:testpass

我不太确定您如何使用 Crypt::OpenSSL::RSA 执行此操作 - 似乎没有任何选项可以为私钥指定密码.

I'm less sure how you do this using Crypt::OpenSSL::RSA - there doesn't seem to be any option to specify a passphrase to a private key.

我认为您因此需要先使用 Crypt::CBC 来解密私钥.我无法对此进行测试,因为我要安装大量依赖项.

I think you therefore need to use Crypt::CBC to decrypt the private key first. I can't test this, because I've got a load of dependencies to install.

一些谷歌搜索表明您可以使用 Crypt::PK::RSA 代替.

A bit of googling suggests that you might be able to use Crypt::PK::RSA instead.

作为替代方案 - 使用 IPC::Open2 并启动一个 openssl 进程来完成这些事情,而根本不使用库.

And as an alernative - use IPC::Open2 and start an openssl process to do the things without using libraries at all.

例如

my $keystring = `openssl rsa -passin pass:testpass -in test_id.enc`;

不是很好,但它会起作用.(并测试它确实有效)

Not very nice, but it'll work. (and test it does actually work)

这篇关于是否可以在 perl 中使用 SSH 私钥对我的数据进行签名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆