因此,省略 perl,只需使用 openssl 手动执行此操作
检查密钥:
ssh-keygen -t rsa -f test_id
openssl rsa -in test_id -check
RSA key ok
所以我们确实有一个“有效”的 RSA 私钥,我们应该能够使用它来加密。
生成比较键
但是如果您使用 openssl 生成密钥对
openssl genrsa -out openssl_gen_rsa
openssl rsa -in openssl_gen_rsa -pubout -out openssl_gen_rsa.out
看起来你需要的命令是:
openssl rsautl -inkey test_id -in test_file.txt -encrypt -out test_file.enc
(使用私钥加密,因此您可以使用公钥解密 - 这实际上与签名非常相似 - 通常您不会这样做)。
问题是 - 如果您比较生成的公钥,它们不匹配。test_id.pub
看起来像(是的,这是真的,不,我只是用它来测试!)
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKfjRD+Gb5EE+SgOy7eoT0siQaAqfSY7KI2wkdrdygnJ+ccW/uMCtCVPhpz00u3EW2Gz1WI DteLKppjvUem1lKb8Tt2EWBQGyFOYKp44r3AJZgTcxLeDdqSUoiPsjWf1aUqy2Z1fBgtG+QOa7bpA8km6CbsORYX/TVg4B6vvdkkH K8WcmzBBF3rGsTCM3VXPp56bPoMCbwCsXvIjejmq+JdGHyxUmCxe1PrPyvmoYX3OUqpFBYIjeLWGDI9EXS6jA/r7viIAxdllvulPg IJ+4mdYzKN+T1ME0X0c+ZdFTMdeUnB9/TZmJr1j8Q/4SQm+3J9CiwtVXKxdkDsDObkcDp root@raspberrypi
我生成的密钥文件如下所示:
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDG8i33AuEp1wqbJgkEsnOmQim3
QT76B/oxsVGfJEDX3h4A6CD+ypBbfhhIn0GlfHanYvcGlpOJIlk3fzspbZNeoPJS
T4a0zQ0z8uJkugl8utyl9WR4tpgBRmzXZ42T/f4QSNqjDxUidRp5zPnXs9aRDtWb
XptswiGL3eVHMpbSnwIDAQAB
-----END PUBLIC KEY-----
我可以使用我生成的对(使用公钥加密,使用私钥解密):
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
这有效。
将 OpenSSH 私钥转换为 RSA 公钥
因此,如果我们通过 openssl 运行您的 ssh 私钥:
openssl rsa -in test_id -pubout -out test_id.openssl.pub
We get:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyn40Q/hm+RBPkoDsu3qE
9LIkGgKn0mOyiNsJHa3coJyfnHFv7jArQlT4ac9NLtxFths9ViA7XiyqaY71HptZ
Sm/E7dhFgUBshTmCqeOK9wCWYE3MS3g3aklKIj7I1n9WlKstmdXwYLRvkDmu26QP
JJugm7DkWF/01YOAer73ZJByvFnJswQRd6xrEwjN1Vz6eemz6DAm8ArF7yI3o5qv
iXRh8sVJgsXtT6z8r5qGF9zlKqRQWCI3i1hgyPRF0uowP6+74iAMXZZb7pT4CCfu
JnWMyjfk9TBNF9HPmXRUzHXlJwff02Zia9Y/EP+EkJvtyfQosLVVysXZA7Azm5HA
6QIDAQAB
-----END PUBLIC KEY-----
这甚至不是与 id_rsa.pub 文件远程相似的编码 - 我想这就是为什么你会遇到这个问题。
openssl rsautl -inkey test_id.openssl.pub -pubin -in test_file.txt -encrypt -out test_file.openssl.pub.enc
现在可以了,您可以使用您的test_id
私钥:
openssl rsautl -inkey test_id -in test_file.openssl.pub.enc -decrypt
所以是的 - 由于某种原因,ssh-keygen 生成的公钥与 openssl 期望的格式不同,因此它不起作用。
使用 openssh 密钥进行验证
不管怎样,回到原来的例子——使用私钥生成签名:
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
但验证步骤won't使用生成的 ssh 密钥进行工作。
那么这是否回答了您的问题:possible
?恐怕我不知道 ssh 公钥与“普通”rsa 公钥有何不同。
因此,我怀疑您的代码甚至不需要那么复杂 - 我认为您不需要 pkcs 填充您的密钥文件。
E.g.
#!/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 填充线)。
加密私钥(密码)
以下来自评论:
If your id_rsa
设置了密码短语,您将得到如下内容:
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,B44716076DD8B7D2B5E909BB8F70B48B
您可以再次使用 openssl 手动解密:
openssl rsa -in test_id.enc
Enter pass phrase for test_id.enc:
Or:
openssl rsa -in test_id.enc -passin pass:testpass
我不太确定你如何使用Crypt::OpenSSL::RSA
- 似乎没有任何选项可以指定私钥的密码。
我认为你因此需要使用Crypt::CBC
首先解密私钥。我无法对此进行测试,因为我需要安装大量依赖项。
一些谷歌搜索表明您可能可以使用Crypt::PK::RSA https://metacpan.org/pod/Crypt::PK::RSA反而。
作为替代方案 - 使用IPC::Open2
并开始openssl
完全不使用库来完成这些事情的过程。
e.g.
my $keystring = `openssl rsa -passin pass:testpass -in test_id.enc`;
不太好,但它会起作用。 (并测试它确实有效)