Generate SSH keypair form PHP
Solution 1
This is based on Converting an OpenSSL generated RSA public key to OpenSSH format (PHP). Thanks 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);
}
?>
Solution 2
I would use phpseclib, a pure PHP RSA implementation:
<?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";
?>
Sample output:
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-----
Source: http://phpseclib.sourceforge.net/rsa/examples.html#openssh
Solution 3
Has anybody tried this?
ssh-keygen -q -N place_your_passphrase_here -t rsa -f ~/.ssh/id_rsa
It's worked for me
Solution 4
Check the manpage of ssh-keygen
to find out how to execute it without any prompts.
http://linux.die.net/man/1/ssh-keygen
Solution 5
This code uses only built-in PHP openssl
functions.
It generates keys in a portable PEM format, suitable for use with most 3rd party software.
<?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');
}
adityap
Updated on July 27, 2022Comments
-
adityap almost 2 years
I want to generate ssh keypair from php can anyone please guide me how to do it? I have tried the shell_exec but the shell asks questions so that command does not work. I would like to specify filename and path in which to put the keys after generation.
-
adityap almost 13 yearsit seems that -q option silent the ssh-keygen but then how would i specify the filename and the directory??
-
symcbean almost 13 yearsFrom the link provided by ThiefMaster: "ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile] " or use proc_open() to handle interactive I/O
-
adityap almost 13 yearsgot it working... with this command ssh-keygen -f /path/to/file -N ''
-
am1 over 4 yearsI'm trying to use the built-in Openssl functions to generate a ED25519 keypair, but it's not supported right now, or?
-
mistiry over 3 yearsThis worked perfectly. I increased the private_key_bits to 4096 though.
-
Firewizz almost 3 yearsExcellent, this worked for me to overcome the "Enter file in which to save the key" question, thanks.