-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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
x/crypto/ssh: handshake failed: ssh: unsupported DSA key size 2048 #23751
Comments
/cc @hanwen |
See RFC 4253 , sec 6.6, which refers to https://csrc.nist.gov/csrc/media/publications/fips/186/2/archive/2000-01-27/documents/fips186-2.pdf try using a different type of key. Adding DSA was a mistake, and OpenSSH has deprecated them starting 7.0 |
So I'm all for using a different type of key, but in this case the challenge is we don't control the host to which we are sending files. The remote host is an IBM Sterling File Gateway and the customer in this case has simply implemented a DSS host key. This is far afield of my area of expertise, but does the reference to larger key sizes in FIPS 186-3 nullify the key size limitation previously referenced in 186-2? |
https://csrc.nist.gov/csrc/media/publications/fips/186/3/archive/2009-06-25/documents/fips_186-3.pdf lists the suggested hash sizes (N), which would be 224 for 2048 bits; if you can use a smaller size for the hash, but then SHA1 (160 bits) would be the weakest link in the signature scheme. That said, it's possible that there exists some variant of this that does so anyway. My suggestion is to find an open source client/server that supports your device and see what they are doing. It should be fairly easy to test the code against your device. for reference, this what made me put the check in, #19424 , which suggests an open source (probably openssh) version of this. |
probably not openssh. $ ssh-keygen -f /tmp/ds -t dsa -b 2048 |
actually no, see https://zonena.me/2014/02/using-2048-bit-dsa-keys-with-openssh/ |
you'd get 160 bits of hash, which then goes into I think this here just puts the 160 bits of sha1 into 256 bits, leaving the rest 0. https://android.googlesource.com/platform/external/boringssl/+/ed3d82f35eb0aa9d81f2398c2142ba07dfc1acee/src/crypto/dsa/dsa.c#696 I suspect it might work if you set the blob buffer to 32byte after all. Can you generate a key like above, configure it in ~/.authorized_keys, and experiment a bit? |
I'll take a look at trying to generate a DSA key that is 2048 today. In the meantime I thought I'd mention that what makes this sticky is the fact that my SSH client on Ubuntu is able to connect to their SFTP site (if I explicitly enable the DSS host keys) and that clients like WinSCP are able to connect without an issue. This gives the customer the impression that their side of the connection is fine, which technically maybe it is, even if it is non-standard. In the meantime I thought perhaps posting a redacted WinSCP log for a successful connection may help. In particular this section highlighting the key being used:
|
Just for fun and record: I also run into this issue today and took a look into my key archive. The original ssh.com client created DSA-2048 keys by default back then. Could be people still use an old ssh version :)
The latest version goes for rsa by default: |
Got the same issue on trying to connect to |
We've just come across this with rclone and some but not all Here is the forum thread for more info This reproduces it
The server identifies itself as
|
I made a small patch to x/crypto/ssh and one of my users confirmed that it fixes the problem for them. diff --git a/golang.org/x/crypto/ssh/keys.go b/golang.org/x/crypto/ssh/keys.go
index 06f537c13..77d7b66fa 100644
--- a/vendor/golang.org/x/crypto/ssh/keys.go
+++ b/vendor/golang.org/x/crypto/ssh/keys.go
@@ -412,7 +412,7 @@ func checkDSAParams(param *dsa.Parameters) error {
// SSH specifies FIPS 186-2, which only provided a single size
// (1024 bits) DSA key. FIPS 186-3 allows for larger key
// sizes, which would confuse SSH.
- if l := param.P.BitLen(); l != 1024 {
+ if l := param.P.BitLen(); l != 1024 && l != 2048 {
return fmt.Errorf("ssh: unsupported DSA key size %d", l)
} Is there any interest in merging a proper version of the above? I'd need to do a bit of reasearch into exactly what FIPS 186-3 says. |
Hello @ncw, I run into the same problem. What's the workaround that you adopted? Working with your own fork + patch? Many Thanks |
The user has been happy running on the patched version I sent them - I haven't forked the library. It would be nice to get this very small patch into the library - what do you think @hanwen ? |
Hey @hanwen Is it possible to include the changes mentioned by @ncw. Can you please look at these changes urgently? |
Hey, I've stepped down as maintainer of the Go SSH package. Please talk to @FiloSottile |
I made a small patch here #23751 (comment) which my users say fixes this problem @FiloSottile I've no idea whether it is sensible though so some guidance here would be much appreciated! |
Hi, I've been using @ncw code as workaround for the time being to connect to the ssh server running in target device (we've no control on it to eventually change configuration). |
I was honestly hoping to remove DSA support altogether, in part because we only support insecure key sizes, so to reduce the attack surface (which has led to client and server DoS in the past). I guess not allowing larger key sizes is a bit contradictory though. First though I would like to figure out two things:
Hopefully what's happening is that the server has other keys and if we drop DSA support it will just pick the better ones. |
Yep, there we go, this server gives priority to DSA but also has an Ed25519 key.
If we were to just deprioritize or remove DSA, this would just work. The problem is that we don't have a host key upgrade mechanism: if some application only accepts the DSA key in On the other hand, anyone currently using DSA is using an insecure key size, so there's an argument for the security exception to the backwards compatibility policy. Finally, since OpenSSH removed DSA support, connecting to these servers using an existing I think the conclusion is to remove DSA, which will actually fix most of these servers, and will only break connections that would have otherwise been insecure. I will file a proposal. |
What would the patch to x/crypto/ssh look like to do that? If there was a simple one then I could get the affected users to try it and we could get some feedback as to whether that will fix their problems. I'm sympathetic to removing DSA, but I don't know how many existing users that will break - has anyone done an internet wide scan of supported SSH auth mechanisms I wonder? I found this https://github.com/ofalk/scanssh/wiki plus a paper from 2000... |
Haven't tested it, but it should be just a matter of deleting this switch case. https://github.com/golang/crypto/blob/948cd5f35899cbf089c620b3caeac9b60fa08704/ssh/keys.go#L62-L63
OpenSSH dropped support five years ago. I am not particularly worried. |
Hello @FiloSottile, I tried the proposed change and I can say that is working for some devices that required @ncw patch but not working for all. Getting some errors: Code used: crypto/ssh/keys.go
@@ -59,8 +59,6 @@ func parsePubKey(in []byte, algo string) (pubKey PublicKey, rest []byte, err err
switch algo {
case KeyAlgoRSA:
return parseRSA(in)
- case KeyAlgoDSA:
- return parseDSA(in)
case KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521:
return parseECDSA(in)
case KeyAlgoSKECDSA256:
@@ -412,7 +410,7 @@ func checkDSAParams(param *dsa.Parameters) error {
// SSH specifies FIPS 186-2, which only provided a single size
// (1024 bits) DSA key. FIPS 186-3 allows for larger key
// sizes, which would confuse SSH.
- if l := param.P.BitLen(); l != 1024 && l != 2048 {
+ if l := param.P.BitLen(); l != 1024 {
return fmt.Errorf("ssh: unsupported DSA key size %d", l)
} Thanks, GL |
I just read through the original thread on the rclone forum and the user said
So @FiloSottile your suggestion of removing DSA seems like a good one and fixes the two known cases we've come across! |
@FiloSottile openssh supports 2048 and 4096 bit host key sizes if you add a Would be nice to see support in this golang module |
We are seeing some odd behavior connecting to a customer SFTP site with a username and password. This code is working for all other tested endpoints.
I see a section of code in the crypto/keys.go file in the function checkDSAParams that fails if the key length is not 1024, but since I am able to connect to that SFTP with ssh and other SFTP clients, I'm not sure why that restriction is being enforced in Go.
What version of Go are you using (
go version
)?go1.9.2 linux/amd64
Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (
go env
)?GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/go"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0"
CXX="g++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
What did you do?
Attempting to establish a connection to a remote SFTP server.
ssh.Dial("tcp", config.SftpServer+":"+string(config.SftpPort), sshConfig)
If possible, provide a recipe for reproducing the error.
A complete runnable program is good.
A link on play.golang.org is best.
What did you expect to see?
A successful SSH handshake and authentication.
What did you see instead?
An error: ssh: handshake failed: ssh: unsupported DSA key size 2048
The text was updated successfully, but these errors were encountered: