sshtools / maverick-synergy

Next Generation Java SSH API
https://jadaptive.com
GNU Lesser General Public License v3.0
96 stars 26 forks source link

Add support for `rsa-sha2-***` signing algorithm for CA signed certificates #21

Closed iamgollum closed 3 years ago

iamgollum commented 3 years ago

Observation

Currently the Signing CA: RSA uses ssh-rsa which is deprecated.

From #14, certificate signing with github extension produces:

        Type: ssh-rsa-cert-v01@openssh.com user certificate
        Public key: RSA-CERT SHA256:JLm/c5O3ZbLd2/7pD8Z/PsHM8TiXJjx7jDHeJ4If1QA
        Signing CA: RSA SHA256:UpGjC+XHqiqmky+maxVXUrH3ek/+PS5K6ZjEWLRKOZU (using ssh-rsa)
        Key ID: "KEY-IDENTITY"
        Serial: 0
        Valid: from 2021-05-19T19:00:00 to 2021-08-17T19:00:00
        Principals: (none)
        Critical Options: (none)
        Extensions:
                permit-X11-forwarding
                permit-agent-forwarding
                permit-port-forwarding
                permit-pty
                permit-user-rc
                login@github.ibm.com UNKNOWN OPTION (len 16)

**This fails to authenticate because its not rsa-sha2-***.**

RSA keys: Add support for rsa-sha2-256 and rsa-sha2-512

Looks like this ->

Signing CA: RSA SHA256:rzmG+gyHbxsvaD1LkehnMjsIrzOAavGtlExpq9MOhc4 (using rsa-sha2-512)

RFC: https://tools.ietf.org/rfc/rfc8332.txt

This memo updates RFCs 4252 and 4253 to define new public key
   algorithms for use of RSA keys with SHA-256 and SHA-512 for server
   and client authentication in SSH connections.

New RSA Public Key Algorithms

This memo adopts the style and conventions of [RFC4253] in specifying how use of a public key algorithm is indicated in SSH.

The following new public key algorithms are defined:

 rsa-sha2-256        RECOMMENDED    sign    Raw RSA key
 rsa-sha2-512        OPTIONAL       sign    Raw RSA key

These algorithms are suitable for use both in the SSH transport layer [RFC4253] for server authentication and in the authentication layer [RFC4252] for client authentication.

Since RSA keys are not dependent on the choice of hash function, the new public key algorithms reuse the "ssh-rsa" public key format as defined in [RFC4253]:

string "ssh-rsa" mpint e mpint n

All aspects of the "ssh-rsa" format are kept, including the encoded string "ssh-rsa". This allows existing RSA keys to be used with the new public key algorithms, without requiring re-encoding or affecting already trusted key fingerprints.

Signing and verifying using these algorithms is performed according to the RSASSA-PKCS1-v1_5 scheme in [RFC8017] using SHA-2 [SHS] as hash.

For the algorithm "rsa-sha2-256", the hash used is SHA-256. For the algorithm "rsa-sha2-512", the hash used is SHA-512.

ludup commented 3 years ago

We already support the core rsa-sha2-256 and rsa-sha2-512 signature types.

Have you tried signing a certificate using a key that has one of these as its public key?

You can convert any ssh-rsa key to sign with these using the helper methods in SshKeyUtils.

I just tried the code below, it failed initially but with a couple of minor tweaks that are now committed it passes so OpenSSH is at least parsing the key and not complaining about the signature. I've not tested using the certificate for authentication, and I still need to look at how to handle the specific certificate types for these automatically.

    SshKeyPair pair = SshKeyUtils.makeRSAWithSHA256Signature(
            SshKeyPairGenerator.generateKeyPair(SshKeyPairGenerator.SSH2_RSA));

    SshKeyPair ca = 
            SshKeyUtils.makeRSAWithSHA256Signature(
                    SshKeyPairGenerator.generateKeyPair(SshKeyPairGenerator.SSH2_RSA));

    SshCertificate cert = SshCertificateAuthority.generateCertificate(pair, 0L, 
            OpenSshCertificate.SSH_CERT_TYPE_USER, "KEY-IDENTITY", 
            "john", 365, 
            new CertificateExtension.Builder().defaultExtensions().build(), ca);

    SshKeyUtils.savePrivateKey(pair, "xxxxx", "User SHA2", new File("test"));
    SshKeyUtils.saveCertificate(cert, "xxxxx", "Cert SHA2", new File("test"));

    System.out.println(Utils.exec("ssh-keygen", "-l", "-f", "test-cert.pub"));
iamgollum commented 3 years ago

@ludup your the best! I should have dug deeper since I have used the SshKeyUtils before. I was reading that ssh-keygen does do a conversion underneath. I will try this out.

iamgollum commented 3 years ago

@ludup everything works! THank you very much

iamgollum commented 3 years ago

@ludup when will RC7 be officially released?

ludup commented 3 years ago

RC7 has now been released.

iamgollum commented 3 years ago

@ludup I am all set. Thank you for everything!