4

I'm trying to find a way to validate that two SSH2 keys, one private and one public, belong to the same key pair. I have used JSch for loading and parsing the private key.

Update: A snippet that could show how to regenerate the public key from the private key (SSH2 RSA) would solve the problem.

Andrei Savu
  • 8,525
  • 7
  • 46
  • 53
  • A short example would be awesome. – Andrei Savu Dec 13 '10 at 12:22
  • Well, as you can see in the RSA JCE code sample in my answer below, there isn't really anything quick or brief about using the JCE API. But the example is basically code annotated with a tutorial narrative – Kim Burgaard Dec 15 '10 at 12:15
  • I thought the whole point of public/private key pairs is that it was really really hard to generate one from the other. Maybe I'm missing something :/ –  Dec 21 '10 at 22:15

4 Answers4

9

You could do this with the BouncyCastle lightweight API.

For example:

InputStream in = new FileInputStream("path/to/private/key");
AsymmetricKeyParameter privateKey = PrivateKeyFactory.createKey(in);
RSAPrivateCrtKeyParameters rsaPrivateKey = (RSAPrivateCrtKeyParameters)privateKey;
BigInteger modulus = rsaPrivateKey.getModulus();
BigInteger publicExponent = rsaPrivateKey.getPublicExponent();
RSAKeyParameters publicKeyParams = new RSAKeyParameters(false, modulus, publicExponent);

The RSAKeyParameters class represents the actual key.

Hope that helps!

Cameron Skinner
  • 51,692
  • 2
  • 65
  • 86
  • By the way, I recommend **not** using the JCE. It's just too painful. BouncyCastle is still pure Java and if you really want to you can use it as a JCE provider. – Cameron Skinner Dec 20 '10 at 12:53
2

I've wrote this util method using Java security (plain J2SE):

public static boolean validateRSAKeyPair(RSAPrivateCrtKey privateKey, RSAPublicKey publicKey) {
    BigInteger n = publicKey.getModulus();
    BigInteger e = publicKey.getPublicExponent();
    BigInteger d = privateKey.getPrivateExponent();
    BigInteger p = privateKey.getPrimeP();
    BigInteger q = privateKey.getPrimeQ();

    BigInteger pq = p.multiply(q);//shold equal to n
    BigInteger eulerMod = p.add(NEGATIVE_ONE).multiply(q.add(NEGATIVE_ONE));// φ(n)=(p-1)*(q-1)
    BigInteger mod = d.multiply(e).mod(eulerMod);// (d*e) mod φ(n), should be 1
    return n.equals(pq) && BigInteger.ONE.equals(mod);
}

It verifies RSA key pair by parameters of RSA algorithm.

1

Maybe this is what you're looking for: How do you test a public/private DSA keypair?

Update: For a pure Java solution, take a look at the standardized Java Cryptography Extension (JCE): http://download.oracle.com/javase/1.4.2/docs/guide/security/jce/JCERefGuide.html#KeyGenerator

Update 2: Here's a code sample from RSA (the method named "go" generates a key-pair): http://www.rsa.com/products/bsafe/documentation/cryptoj35html/doc/dev_guide/group__CJ__SAMPLES__RSANOPAD__JCE.html

Update 3: And here's a link that deals with parsing a public key for JCE: How do we convert a String from PEM to DER format

Community
  • 1
  • 1
Kim Burgaard
  • 3,508
  • 18
  • 11
  • Somehow. I need a pure Java solution for doing "ssh-keygen -y -f " - regenerating the public key from the private one (SSH2 RSA format) – Andrei Savu Dec 15 '10 at 11:40
  • Okay, I added a link to JCE. JCE supports RSA, so I think the main challenge is to make sure JCE is configured and set up to read the format that SSH2 uses. You might find this useful too: http://download.oracle.com/javase/1.4.2/docs/guide/security/jce/JCERefGuide.html#AppAå – Kim Burgaard Dec 15 '10 at 11:56
  • That's exactly what I've been trying to use. Unfortunately the documentation is really hard to use. I haven't found a native way for parsing SSH2 RSA keys and that's way I have posted this question here. – Andrei Savu Dec 15 '10 at 12:01
  • I just added a link to a JCE code sample from RSA. Does that help? – Kim Burgaard Dec 15 '10 at 12:02
  • Yes. I don't like the fact that it needs com.rsa.jsafe.crypto.CryptoJ but I believe I can overcome that. – Andrei Savu Dec 15 '10 at 12:13
  • com.rsa.jsafe.crypto.CryptoJ is a vendor-specific security provider. The JCE API stays the same, so if you can find another RSA security provider, then the rest of the code in the sample should work without any further modifications. I would, however, put more faith in RSA's own implementation. I hear they're pretty good with cryptography :-) – Kim Burgaard Dec 15 '10 at 12:17
  • That code sample unfortunately does not solve the SSH2 key parsing problem. – Andrei Savu Dec 15 '10 at 12:17
  • I added a link to another Stackoverflow question that deals with parsing the keys. – Kim Burgaard Dec 15 '10 at 12:26
0

I know is cheating but can you invoke a process like :

ssh-keygen -f ~/.ssh/id_rsa -y > ~/.ssh/id_rsa.pub

See this.

Community
  • 1
  • 1
ahvargas
  • 903
  • 10
  • 17
  • That could work but I can't make the assumption that ssh-keygen exists. A Java solution based on JCE that does the same thing would be great. – Andrei Savu Dec 15 '10 at 12:16