从PHP生成SSH密钥对

10

我想从php生成ssh密钥对,有人可以指导我如何做吗?我已经尝试了shell_exec,但是shell会询问问题,因此该命令无法工作。我想指定生成后放置密钥的文件名和路径。

5个回答

16

这是基于将OpenSSL生成的RSA公钥转换为OpenSSH格式(PHP)的内容。感谢shevron

<?php
$rsaKey = openssl_pkey_new(array( 
              'private_key_bits' => 1024, 
              'private_key_type' => OPENSSL_KEYTYPE_RSA));

$privKey = openssl_pkey_get_private($rsaKey); 
openssl_pkey_export($privKey, $pem); //Private Key
$pubKey = sshEncodePublicKey($rsaKey); //Public Key

$umask = umask(0066); 
file_put_contents('/tmp/test.rsa', $pem); //save private key into file
file_put_contents('/tmp/test.rsa.pub', $pubKey); //save public key into file

print "Private Key:\n $pem \n\n";
echo "Public key:\n$pubKey\n\n";

function sshEncodePublicKey($privKey) {
    $keyInfo = openssl_pkey_get_details($privKey);
    $buffer  = pack("N", 7) . "ssh-rsa" .
    sshEncodeBuffer($keyInfo['rsa']['e']) . 
    sshEncodeBuffer($keyInfo['rsa']['n']);
    return "ssh-rsa " . base64_encode($buffer);
}

function sshEncodeBuffer($buffer) {
    $len = strlen($buffer);
    if (ord($buffer[0]) & 0x80) {
        $len++;
        $buffer = "\x00" . $buffer;
    }
    return pack("Na*", $len, $buffer);
}
?>

这个完美地运行了。不过我把 private_key_bits 增加到了 4096。 - mistiry

12

我会使用phpseclib,一个纯PHP RSA实现

<?php
include('Crypt/RSA.php');

$rsa = new Crypt_RSA();

$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_OPENSSH);

extract($rsa->createKey());
echo "$publickey\r\n\r\n$privatekey";
?>

样例输出:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZw== phpseclib-generated-key

-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
-----END RSA PRIVATE KEY-----

来源:http://phpseclib.sourceforge.net/rsa/examples.html#openssh


9

有人试过这个吗?

ssh-keygen -q -N place_your_passphrase_here -t rsa -f ~/.ssh/id_rsa

这对我来说很有效


很好,这对我克服“输入要保存密钥的文件”问题非常有帮助,谢谢。 - Firewizz

4

似乎“-q”选项会使ssh-keygen静默,但我该如何指定文件名和目录? - adityap
从ThiefMaster提供的链接中: "ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile] " 或使用proc_open()来处理交互式I/O。 - symcbean
2
搞定了...使用以下命令 ssh-keygen -f /path/to/file -N '' - adityap

3
这段代码仅使用内置的PHP openssl函数。
它生成便携式PEM格式的密钥,适用于大多数第三方软件。
<?php

function generateRsaKeyPair(array $config = []): array
{
  $config = array_merge([
    'digest_alg' => 'sha512',
    'private_key_bits' => 2048,
    'private_key_type' => OPENSSL_KEYTYPE_RSA,
  ], $config);

  // Create the keypair
  $key = openssl_pkey_new($config);
  if (!$key) {
    throw new RuntimeException('Unable to generate RSA key pair');
  }

  // Get private key
  openssl_pkey_export($key, $private);
  if (!$private) {
    throw new RuntimeException('Unable to extract private key');
  }

  // Get public key
  $public = openssl_pkey_get_details($key)['key'] ?? null;
  if (!$public) {
    throw new RuntimeException('Unable to extract public key');
  }

  // Free key from memory
  openssl_pkey_free($key);

  // Return both keys
  return compact('public', 'private');
}

我正在尝试使用内置的Openssl函数生成ED25519密钥对,但是现在不支持吗? - am1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接