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

There is an error while parsing ed25519 key generated by SSH Key generator #743

Open
bade7n opened this issue Jan 10, 2025 · 15 comments
Open

Comments

@bade7n
Copy link

bade7n commented Jan 10, 2025

jsch version v 0.2.18

error while trying to import encrypted ed25519 key generated by https://docs.devolutions.net/rdm/commands/tools/ssh-key/ SSH key generator.

-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABAMI6J9el
HWflqdA5w3HO0jAAAAQAAAAAEAAAAAAAAAkEzlhHSSVjdSs45PBdGOVLxFtwybaZ4KIccg
FuZvh5uXQYwxi1HtEDuEcr88w0MWw0VTdx06yaFOIOZ5WxMdDafaeWvZ+XFZfFxtVYAyKR
BrIUJ0MojwdteQ+J/hM8hAjJoSquWTD+1q80hDtP+S7Wo8FfOB4eqKResOg55kgr1a7AMf
nfGadlF8VAPImRsoVg==
-----END OPENSSH PRIVATE KEY-----

The key is missing public part

JSch jsch = new JSch();
KeyPair kpair = KeyPair.load(jsch, privateKey, null);
return kpair.isEncrypted();

// parsing the key gives an empty public part

res = {byte[6][]@2122} 
 0 = {byte[10]@2127} aes256-cbc
 1 = {byte[6]@2129} bcrypt
 2 = {byte[24]@2124} [0, 0, 0, 16, 12, 35, -94, 125, 122, 81, -42, 126, 90, -99, 3, -100, 55, 28, -19, 35, 0, 0, 0, 64]
 3 = {byte[1]@1964} [0]
 4 = {byte[0]@2130} [] <- missing data block here
 5 = {byte[144]@2125} [76, -27, -124, 116, -110, 86, 55, 82, -77, -114, 79, 5, -47, -114, 84, -68, 69, -73, 12, -101, 105, -98, 10, 33, -57, 32, 22, -26, 111, -121, -101, -105, 65, -116, 49, -117, 81, -19, 16, 59, -124, 114, -65, 60, -61, 67, 22, -61, 69, 83, 119, 29, 58, -55, -95, 78, 32, -26, 121, 91, 19, 29, 13, -89, -38, 121, 107, -39, -7, 113, 89, 124, 92, 109, 85, -128, 50, 41, 16, 107, 33, 66, 116, 50, -120, -16, 118, -41, -112, -8, -97, -31, 51, -56, 64, -116, -102, 18, -86, -27, +44 more]
com.jcraft.jsch.JSchException: java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
	at com.jcraft.jsch.KeyPair.load(KeyPair.java:1143)
	at com.jcraft.jsch.KeyPair.load(KeyPair.java:685)
	at jetbrains.buildServer.ssh.CryptUtil.isEncrypted(CryptUtil.java:29)

Initiated by our customer here.

@norrisjeremy
Copy link
Contributor

Hi @bade7n,

If it's missing the public key part as you've indicated, then that would indicate to me that it is not encoded correctly, and that you should instead by contacting the vendor that generated that key.

Thanks,
Jeremy

@bade7n
Copy link
Author

bade7n commented Jan 10, 2025

An interesting part here is that 0.1.x versions work well as just ignores exception in 0.1.72: KeyPair.java:929 (ArrayIndexOutOfBoundsException while eval buf[0] == 's' in ignored catch on line 975.

@norrisjeremy
Copy link
Contributor

I'm not sure why you are opening an issue with us: the key you provided is clearly invalid: why are you not taking up the issue with the vendor who's tool generated an invalid key in the first place?

@bade7n
Copy link
Author

bade7n commented Jan 10, 2025

@norrisjeremy we shared that understanding but in theory public part is not required in case of DeferredKey so maybe there is some logic underneath as openssh works well with it.

@bade7n
Copy link
Author

bade7n commented Jan 10, 2025

As I understand unencrypted public part might be missing by purpose to hide the key identity and its basically not needed as that information is duplicated in encrypted private part.
If you think that jsch would not benefit from supporting that case, just close it and forget. My intention was to inform you about such corner case and maybe to prevent upgrading to 0.2.x version some people who want to use such keys.

@norrisjeremy
Copy link
Contributor

As I understand unencrypted public part might be missing by purpose to hide the key identity and its basically not needed as that information is duplicated in encrypted private part.

Instead of guessing, could you perhaps instead contact the vendor who's tools generated this key in the first place?
Before we start introducing workarounds, we'd like to better understand why the vendor is choosing to generate keys in an ostensibly invalid format.

@norrisjeremy
Copy link
Contributor

norrisjeremy commented Jan 10, 2025

Hi @bade7n,

Additionally, I'm not even able reproduce the reported exception, using the following test case:

import com.jcraft.jsch.JSch;
import com.jcraft.jsch.KeyPair;
import java.util.Arrays;

public class Foo {
  public static void main(String[] args) throws Exception {
    var key = """
      -----BEGIN OPENSSH PRIVATE KEY-----
      b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABBU
      PQlHJLBkOF1EzB92Z54rAAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIKxn
      01gBk+MroNLf5TjynfuaoZLmI/mdztWpL01ySIOEAAAAkEtCYMx9c01TYzW97I3t
      UjRAskPMCptf7L75bUf/HmxvUni/Ht5skcI9WGK78sE8moYZT/g+9bm8X2P6bcLS
      sVY/a86JdXmvoio8I6lz8Wm7JZIhtbu7RHItYUyOkBVAPkfaEmooeNxQMaQdw96S
      1b+wSOP4N/JvD3FbD5TBxBYIwMViMaccbZ5/dj2OMd2XmA==
      -----END OPENSSH PRIVATE KEY-----
      """;
    var kp = KeyPair.load(new JSch(), key.getBytes("UTF-8"), null);
    System.out.println(kp.getKeyTypeString());
    System.out.println(Arrays.toString(kp.getPublicKeyBlob()));
    System.out.println(kp.getFingerPrint());
    System.out.println(kp.isEncrypted());
  }
}

With the above test case, I see the following output and no exceptions thrown:

ssh-ed25519
[0, 0, 0, 11, 115, 115, 104, 45, 101, 100, 50, 53, 53, 49, 57, 0, 0, 0, 32, -84, 103, -45, 88, 1, -109, -29, 43, -96, -46, -33, -27, 56, -14, -99, -5, -102, -95, -110, -26, 35, -7, -99, -50, -43, -87, 47, 77, 114, 72, -125, -124]
37:d1:36:3b:9d:9e:c0:83:97:0b:60:dd:af:ca:47:cc
true

Is there something I'm missing?

Thanks,
Jeremy

@bade7n
Copy link
Author

bade7n commented Jan 10, 2025

yes, wrong key attached, my bad, I've checked too many keys yesterday

var key = "-----BEGIN OPENSSH PRIVATE KEY-----\n" +
                                                "b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABAMI6J9el\n" +
                                                "HWflqdA5w3HO0jAAAAQAAAAAEAAAAAAAAAkEzlhHSSVjdSs45PBdGOVLxFtwybaZ4KIccg\n" +
                                                "FuZvh5uXQYwxi1HtEDuEcr88w0MWw0VTdx06yaFOIOZ5WxMdDafaeWvZ+XFZfFxtVYAyKR\n" +
                                                "BrIUJ0MojwdteQ+J/hM8hAjJoSquWTD+1q80hDtP+S7Wo8FfOB4eqKResOg55kgr1a7AMf\n" +
                                                "nfGadlF8VAPImRsoVg==\n" +
                                                "-----END OPENSSH PRIVATE KEY-----\n"

@norrisjeremy
Copy link
Contributor

Hi @bade7n,

Whilst I am now able to reproduce the reported exception using the new key you provided, I am not keen on adding a workaround to JSch.
We deliberately changed the handling of OpenSSH V1 keys to eliminate the "deferred" key concept in dec14d0.
As part of that change, we must know what the underlying key algorithm is that we are dealing with (even when it is in an encrypted state).
With the state of this problematic key, it is impossible to determine the underlying key algorithm, which in turn presents a problem for us.

Additionally, nothing that I see in the OpenSSH documentation of the key format seems to indicate that the publickey field(s) are optional and can be omitted.

So I would be inclined to push back on the vendor that is producing keys in this format to better understand why they are doing this and if they can instead fix the problem on their end.

Thanks,
Jeremy

@bade7n
Copy link
Author

bade7n commented Jan 10, 2025

Completely agree on that. I've contacted devolutions but it might take a while.

@norrisjeremy
Copy link
Contributor

Hi @bade7n,

Have you also confirmed that OpenSSH itself can handle the provided SSH key correctly?
My quick skimming of the their source code seems to indicate that they too might actually fail on this same key as well, as seen here.
If I'm reading their code correctly, they will fail because the parsed public key field (pubkey) will not match the public key from the decrypted part of the private key field (k).

Thanks,
Jeremy

@bade7n
Copy link
Author

bade7n commented Jan 10, 2025

it could be converted via puttygen back to proper openssh format.

@norrisjeremy
Copy link
Contributor

Hi @bade7n,

Do you happen to know the passphrase to decrypt this key?
That would let us actually test with OpenSSH to see how it handles it.

Thanks,
Jeremy

@bade7n
Copy link
Author

bade7n commented Jan 10, 2025

Passphrase: R2rfgX24Lun9rhGarfjPrVkcdj4DA4

@norrisjeremy
Copy link
Contributor

Hi @bade7n,

My initial testing of this key indicates that not even OpenSSH itself can handle it.
Whenever I try to us it with ssh, I get the following error:

$ ssh -i bad_key w.x.y.z
Load key "bad_key": error in libcrypto

Since OpenSSH itself seems unable to handle it, I am especially disinclined to add a workaround for it to JSch.

Thanks,
Jeremy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants