PKCS#8 SSH keys do not work

I have both PKCS#1 (“BEGIN RSA PRIVATE KEY”) and PKCS#8 (“BEGIN PRIVATE KEY”) keys configured on my Linux servers. I am able to use both with the standard SSH command, but when I create a credential with <create_credential …/> only the PKCS#1 yields an Auth-SSH-Success in the resulting XML report; when I use the PKCS#8 key (same username), I only get Auth-SSH-Failure.

I am using the latest GVM community containers.

Let me know what other information I should supply.

I guess that PKCS#8 should be supported from this post. In the python-gvm docs for the create_credential function, PKCS#1 and PKCS#8 are not mentioned, but PKC#12 is (a typo in the docs, should be PKCS#12).

It also mentions PEM is supported and PKCS#8 formatted keys can be PEM encoded - perhaps you can try the PKCS#8 in PEM format (base64 encoding).

Also, perhaps your can confirm or clarify the details of what you are trying to achieve. It seems you are trying to use GMP/XML to create a SSH key credential in GVM and then configure that credential for an authenticated scan. You can create the credential, but when using it for the authenticated scan you get an Auth-SSH-Failure error in the results of the scan report.

Is that correct?

Yes, you are exactly right. I create credentials using PEM-formatted keys of both types, and the results are as I said.

The python-gvm doc you quoted says the support for various formats depends on the GnuTLS version. The ospd-openvas container shows this installed library:

ii libgnutls30:amd64 3.7.9-2 amd64 GNU TLS library - main runtime library

Would that version support PEM-formatted PKCS#8 keys?

I forgot to mention that both keys are RSA.

I have not had time to test this yet. I typically generate keys using ssh-keygen, which I noticed generates PKCS#1 by default. However, I noticed that OpenSSL library generates PKCS#8 keys by default for all rsa private keys. :thinking:

Today I verified the use of PKCS8 keys. I typically use keys generated with ssh-keygen which creates an SSH specific format with the header -----BEGIN OPENSSH PRIVATE KEY----- and are not PKCS8.

Using PKCS#8 keys generated with openssl, the scan was successful. Here is the method I used to generate the keys and configure the scan.

  1. Create a private key using OpenSSL (all OpenSSL versions since v1.0 have used PKCS8 by default)
openssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:2048
  1. Create the associated public key
openssl rsa -pubout -in private.pem -out public_key.pem
  1. If using a version of OpenSSL before V1.0 (circa 2010) Convert the private.pem into PKCS8 format unencrypted private key (this is only required for older versions of OpenSSL that create PKCS#1 keys be default.). Otherwise, this step will have no effect on the key from input/output.
openssl pkcs8 -topk8 -in private.pem -nocrypt -out private_pkcs8.pem
  1. Convert the public key into OpenSSH PKCS8 format
ssh-keygen -f public_key.pem -i -m PKCS8 > public_key.openssh
  1. Configure the target host by adding the OpenSSH public key (public_key.openssh) to a user’s ~/.ssh/authorized_keys file.
  2. Test the login via SSH
  3. Use the PKCS8 private key (private_pkcs8.pem) to create a Greenbone credential
  4. Use "Advanced scan wizard” to create a task and add the PKCS8 credential as the SSH authentication.

I followed your steps exactly, with the same result I have been getting: Auth-SSH-Failure in the resulting XML report. I am using the current community docker containers. What can I check? Do you have any suggestions for me?

The first thing I would check would be to compare the contents of the PostgreSQL database between loading the credential through the GSA web interface, and loading the same credential via python-gvm / GMP. I assume you have enabled the gvm-cli feature using the instructions from the official Docker containers workflow and using python-gvm to interact with it via the same host as the containers are installed on.

If that’s the case, you could post your Python script here and perhaps it can be reviewed. Also, I believe the create_credential() function should accept the string of the private key, not the location of a file containing the private key, and although I have not checked, I doubt that the gvmd/GMP is verifying the submitted contents for validity.