Putty Private Key generated by SSH is not always valid.
I wrote a test node js script to do the following:
- generate a rsa key pair
- using the generated rsa private key, generate the putty private key using forge
- using the same generated rsa private key, generate the putty private key using the 'puttygen' command line.
- compare the two putty private keys.
Out of every 100 times, about 7 to 10 times the ppk generated is not the same. When it is not the same, the ppk by forge cannot be loaded or used by putty, however the ppk by puttygen is ok.
Attached is the test script.
@yammelvin
I've tried to run the test script, but I ran into issue with the puttygen parameters -C and -O
The documentation I've found for PuTTYgen does not mention these parameters either:
https://tartarus.org/~simon/putty-snapshots/htmldoc/Chapter8.html#puttygen-cli
The options supported on the command line are:
-t keytype Type of key to generate. You can select rsa, dsa, ecdsa, eddsa, ed25519, ed448, or rsa1. See section 8.2.2. -b bits Size of the key to generate, in bits. See section 8.2.3. --primes method Method for generating prime numbers. You can select probable, proven, and proven-even. See section 8.2.4. --strong-rsa When generating an RSA key, make sure the prime factors of the key modulus are ‘strong primes’. See section 8.2.4. --ppk-param key=value,... Allows setting all the same details of the PPK save file format described in section 8.2.13.
@mathieucaroff
I am using puttygen release 0.78 on Ubuntu 22.04 LTS. Perhaps you are using an old version?
The official website is https://www.puttygen.com/#Download_PuTTYgen_for_UbuntuLinux
-C and -O are valid options as stated in the website.
The following are the outputs of puttygen and -C and -O are definitely valid options.
> puttygen
Usage: puttygen ( keyfile | -t type [ -b bits ] )
[ -C comment ] [ -P ] [ -q ]
[ -o output-keyfile ] [ -O type | -l | -L | -p ]
Use "puttygen --help" for more detail.
> puttygen --help
PuTTYgen: key generator and converter for the PuTTY tools
Release 0.78
Usage: puttygen ( keyfile | -t type [ -b bits ] )
[ -C comment ] [ -P ] [ -q ]
[ -o output-keyfile ] [ -O type | -l | -L | -p ]
-t specify key type when generating:
eddsa, ecdsa, rsa, dsa, rsa1 use with -b
ed25519, ed448 special cases of eddsa
-b specify number of bits when generating key
-C change or specify key comment
-P change key passphrase
-q quiet: do not display progress bar
-O specify output type:
private output PuTTY private key format
private-openssh export OpenSSH private key
private-openssh-new export OpenSSH private key (force new format)
private-sshcom export ssh.com private key
public RFC 4716 / ssh.com public key
public-openssh OpenSSH public key
fingerprint output the key fingerprint
cert-info print certificate information
text output the key components as 'name=0x####'
-o specify output file
-l equivalent to `-O fingerprint'
-L equivalent to `-O public-openssh'
-p equivalent to `-O public'
--cert-info equivalent to `-O cert-info'
--dump equivalent to `-O text'
-E fptype specify fingerprint output type:
sha256, md5, sha256-cert, md5-cert
--certificate file incorporate a certificate into the key
--remove-certificate remove any certificate from the key
--reencrypt load a key and save it with fresh encryption
--old-passphrase file
specify file containing old key passphrase
--new-passphrase file
specify file containing new key passphrase
--random-device device
specify device to read entropy from (e.g. /dev/urandom)
--primes <type> select prime-generation method:
probable conventional probabilistic prime finding
proven numbers that have been proven to be prime
proven-even also try harder for an even distribution
--strong-rsa use "strong" primes as RSA key factors
--ppk-param <key>=<value>[,<key>=<value>,...]
specify parameters when writing PuTTY private key file format:
version PPK format version (min 2, max 3, default 3)
kdf key derivation function (argon2id, argon2i, argon2d)
memory Kbyte of memory to use in passphrase hash
(default 8192)
time approx milliseconds to hash for (default 100)
passes number of hash passes to run (alternative to 'time')
parallelism number of parallelisable threads in the hash function
(default 1)
@mathieucaroff
At the time of writing the test script.
I was using puttygen 0.76 which by default generates ppk version 2.
I just rerun the script using puttygen 0.78 which by default generates ppk version 3.
With puttygen 0.78, you need to add the option --ppk-param version=2 to generate ppk version 2.
Attached is the updated test script for putty 0.78. testforgeputty.zip
In any case, node-forge generates ppk version 2 which is obsolete. putty now uses ppk version 3.