Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

error: "sha1 is not supported by this backend for RSA signing" #2259

Open
pghmcfc opened this issue Jun 23, 2023 · 8 comments · May be fixed by #2345
Open

error: "sha1 is not supported by this backend for RSA signing" #2259

pghmcfc opened this issue Jun 23, 2023 · 8 comments · May be fixed by #2345

Comments

@pghmcfc
Copy link
Contributor

pghmcfc commented Jun 23, 2023

This issue was originally reported in Red Hat Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2214984

When connecting to an ssh server that provides an rsa host key and the host key is known (either by a known_hosts file or by previous connection attempts), paramiko fails with "cryptography.exceptions.UnsupportedAlgorithm: sha1 is not supported by this backend for RSA signing", giving the following traceback:

  File "/usr/lib/python3.9/site-packages/paramiko/client.py", line 421, in connect
    t.start_client(timeout=timeout)
  File "/usr/lib/python3.9/site-packages/paramiko/transport.py", line 699, in start_client
    raise e
  File "/usr/lib/python3.9/site-packages/paramiko/transport.py", line 2130, in run
    self.kex_engine.parse_next(ptype, m)
  File "/usr/lib/python3.9/site-packages/paramiko/kex_curve25519.py", line 64, in parse_next
    return self._parse_kexecdh_reply(m)
  File "/usr/lib/python3.9/site-packages/paramiko/kex_curve25519.py", line 130, in _parse_kexecdh_reply
    self.transport._verify_key(peer_host_key_bytes, sig)
  File "/usr/lib/python3.9/site-packages/paramiko/transport.py", line 1941, in _verify_key
    if not key.verify_ssh_sig(self.H, Message(sig)):
  File "/usr/lib/python3.9/site-packages/paramiko/rsakey.py", line 152, in verify_ssh_sig
    key.verify(
  File "/usr/lib64/python3.9/site-packages/cryptography/hazmat/backends/openssl/rsa.py", line 571, in verify
    return _rsa_sig_verify(
  File "/usr/lib64/python3.9/site-packages/cryptography/hazmat/backends/openssl/rsa.py", line 270, in _rsa_sig_verify
    pkey_ctx = _rsa_sig_setup(
  File "/usr/lib64/python3.9/site-packages/cryptography/hazmat/backends/openssl/rsa.py", line 213, in _rsa_sig_setup
    raise UnsupportedAlgorithm(
cryptography.exceptions.UnsupportedAlgorithm: sha1 is not supported by this backend for RSA signing.

This is with paramiko 2.12.0 on Red Hat Enterprise Linux 9 (or a clone thereof), where sha1 is not supported for cryptographic operations.

Steps to Reproduce:

  1. setup an ssh server with an rsa host key
  2. clear this host key from any known_hosts files
  3. connect twice

Actual results:
the first connect succeeds, the second connect fails with the trace above.

Expected results:
both connects successful

The original reporter provided a couple of attachments to help reproduce this issue, running an ssh server in a container. I can attach those and the accompanying instructions here if it's helpful.

My initial thought is that paramiko should trap this exception and treat the case the same as if the host key was not found, possibly providing some warning that that had happened so that users would understand why an existing key was ignored.

@bskinn
Copy link
Contributor

bskinn commented Jul 8, 2023

Thanks for transferring this report over here, we never would have seen it otherwise.

If I understand correctly what's going on, this error occurs because a server is crafting its host keys with an obsolete, insecure hashing algorithm, in SHA1.

Isn't.... the best solution here to upgrade the server so that it can use a modern, secure algorithm? Instead of changing paramiko to blithely ignore a security-relevant error raised out of cryptography?

I recognize that a server host key isn't on the same level of importance as an SSL key pair, since server host keys aren't usually backed by third-party CA certs and such, but this seems like an imprudent way to handle the situation.

Rather than accepting this connection by default and warning about an obsolete key being ignored, it seems to me a better solution would be an 'opt in' flag that a user would have to specify... a skip_host_key_verification boolean or something.

What do you think?

@bskinn bskinn added the Keys label Jul 8, 2023
@pghmcfc
Copy link
Contributor Author

pghmcfc commented Jul 8, 2023

@bskinn, I've updated the bugzilla ticket with your comment so we can get the original reporter's response. I personally would be happy enough with an option to ignore this issue. Regarding updating the server, that may be very tricky in some cases, such as for an embedded device with a server that doesn't support anything more modern in terms of key algorithms.

@bskinn
Copy link
Contributor

bskinn commented Jul 8, 2023

I've updated the bugzilla ticket with your comment so we can get the original reporter's response.

Great, thanks!

I personally would be happy enough with an option to ignore this issue.

👍, it seems to me that's the best approach for the 2.x maintenance line. We'd welcome a PR from anyone interested in working on it.

Do you know, would the new experimental auth strategy features allow user-side handling of this hitch? (3.2 CHANGELOG, scroll down to the first red callout.) One of the big goals of that new machinery (including some as-yet-unimplemented pieces) is to allow users to cope with their hardware weirdness themselves, instead of fixes needed upstream.

We'd also welcome help here, again from anyone interested, testing those new experimental features to see if they can resolve this.

Regarding updating the server, that may be very tricky in some cases, such as for an embedded device with a server that doesn't support anything more modern in terms of key algorithms.

I know, cognitively, that this is a problem, but I've never dealt with it myself and so I keep forgetting to consider it.

Can you help me out by providing some concrete examples of embedded devices like this? Control hardware for chemical process industry? Manufacturing equipment? IoT? Controllers in cars? The specificity will help the category stick in mind.

@pghmcfc
Copy link
Contributor Author

pghmcfc commented Jul 8, 2023

Can you help me out by providing some concrete examples of embedded devices like this? Control hardware for chemical process industry? Manufacturing equipment? IoT? Controllers in cars? The specificity will help the category stick in mind.

I don't have anything that I use paramiko with. However, I have a couple of Ubiquity WiFi access points (which get regular updates by the way, unusual for this sort of device I think) and I can access them via openssh but I need entries like these in my ~/.ssh/config:

Host front.ap-ac-lr
  HostName front.ap-ac-lr.intranet.example.com
  User paul
  IdentityFile ~/.ssh/id_rsa
  PubkeyAcceptedAlgorithms +ssh-rsa
  RequiredRSASize 1024

Host rear.ap-ac-lr
  HostName rear.ap-ac-lr.intranet.example.com
  User paul
  IdentityFile ~/.ssh/id_rsa
  PubkeyAcceptedAlgorithms +ssh-rsa
  RequiredRSASize 1024

@pghmcfc
Copy link
Contributor Author

pghmcfc commented Jul 12, 2023

Feedback from reporter:

Of course the best solution is to upgrade the server, but sometimes this isn't a valid option. Either because the server is a proprietary blackbox or it must be kept at a specific stable version, or, simply because noone cared to provide an update to the software to support other algorithms yet. In my case it's about jenkins, it seems only to support rsa sha1 hostkeys for the ssh configuration interface.

Sure, I'm fine with a "skip_host_key_verification" flag if this covers outdated algorithms as well (and not only stuff like mismatching fingerprints).

Thanks!

@bskinn
Copy link
Contributor

bskinn commented Jul 25, 2023

Ok, sounds like a 'skip' option would be viable for everyone in the conversation here.

And yes, I would expect a skip flag would skip the verification entirely. Certainly that's the first implementation I'd recommend, and we would consider more granular skip-or-not controls once we determined they're not YAGNI.

I'm going to flag this for bitprophet to review at whatever point in the future he does a pass on the flag, so he can weigh in.

But, I'm confident enough in the feature to request anyone interested prepare a PR to implement this.

@bskinn bskinn added the Feature request eval needed Triage -> maintainer signal label Jul 25, 2023
@bskinn
Copy link
Contributor

bskinn commented Oct 13, 2023

@gubenkoved -- I think you're looking at the wrong part of the codebase.

id_* keys are for client authentication, confirming to the server the identity of the client seeking a connection.

The issue here is host validation -- confirming to the client that the server is who they are expecting to be connecting to.

Also, if the underlying cryptography library in the relevant context doesn't support SHA1, then I don't think it really matters if paramiko still does. OP's exception is being raised from within cryptography.

@gubenkoved
Copy link

Thank you for your answer, @bskinn! I've removed my comment before you replied as I realised sources of my own confusion here.

In my particular case I was able to work around this issue supplying ssh-rsa algorithm as disabled_algorithms to SSHClient.connect methods.

Additionally, I beleive similar issue can appear for the "client authentication" part of the paramiko as well. Here is the sample traceback. I also want to mention FIPS OpenSSL provider as a reason of SHA1 not being available as RSA digest algorithm in my case.

80BBFC66117F0000:error:1C8000AE:Provider routines:rsa_setup_md:digest not allowed:../../source/openssl-3.0.8-provider/providers/implementations/signature/rsa_sig.c:304:digest=sha1
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/dist-packages/paramiko/transport.py", line 2164, in run
    handler(self.auth_handler, m)
  File "/usr/local/lib/python3.10/dist-packages/paramiko/auth_handler.py", line 395, in _parse_service_accept
    sig = self.private_key.sign_ssh_data(blob, algorithm)
  File "/usr/local/lib/python3.10/dist-packages/paramiko/rsakey.py", line 126, in sign_ssh_data
    sig = self.key.sign(
  File "/usr/local/lib/python3.10/dist-packages/cryptography/hazmat/backends/openssl/rsa.py", line 513, in sign
    return _rsa_sig_sign(self._backend, padding, algorithm, self, data)
  File "/usr/local/lib/python3.10/dist-packages/cryptography/hazmat/backends/openssl/rsa.py", line 275, in _rsa_sig_sign
    pkey_ctx = _rsa_sig_setup(
  File "/usr/local/lib/python3.10/dist-packages/cryptography/hazmat/backends/openssl/rsa.py", line 236, in _rsa_sig_setup
    raise UnsupportedAlgorithm(
cryptography.exceptions.UnsupportedAlgorithm: sha1 is not supported by this backend for RSA signing.

pghmcfc added a commit to pghmcfc/paramiko that referenced this issue Jan 11, 2024
Adds _skip_host_key_verification attribute to Transport and
provides a set_skip_host_key_verification method to set or clear
it (default: `False`).

Adds skip_host_key_verification parameter to SSHClient.connect
(default: `False`), which is passed directly to the transport.

Skipping host key verification might be useful in very rare cases
where it is not possible to verify the target's key, for example if
it uses a legacy signature algorithm that is no longer supported by
the client, e.g. in paramiko#2259.
@pghmcfc pghmcfc linked a pull request Jan 11, 2024 that will close this issue
pghmcfc added a commit to pghmcfc/paramiko that referenced this issue Jan 11, 2024
Adds _skip_host_key_verification attribute to Transport and
provides a set_skip_host_key_verification method to set or clear
it (default: `False`).

Adds skip_host_key_verification parameter to SSHClient.connect
(default: `False`), which is passed directly to the transport.

Skipping host key verification might be useful in very rare cases
where it is not possible to verify the target's key, for example if
it uses a legacy signature algorithm that is no longer supported by
the client, e.g. in paramiko#2259.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants