7

I'm reading the wikipedia about public-key Public-key cryptography ( http://en.wikipedia.org/wiki/Public-key_cryptography ) and in it it says:

In the Diffie–Hellman key exchange scheme, each party generates a public/private key pair and distributes the public key... After obtaining an authentic copy of each other's public keys, Alice and Bob can compute a shared secret offline. The shared secret can be used, for instance, as the key for a symmetric cipher.

I'm wondering how to achieve this in Java? i.e., given an arbitrary public-key and an arbitary private-key, how to generate a share-secret from it?

To make it more clear:

Alice has a public/private key pair key_pair_alice,

Bob has a public/private key pair key_pair_bob,

Assuming my understanding is right, there should be a method combine_keys() so that:

combine_keys(key_pair_alice.private, key_pair_bob.public) == 
    combine_keys(key_pair_alice.public, key_pair_bob.private) 

My question is how to implement the combine_keys() method in Java.

Thanks.

shonky linux user
  • 6,131
  • 4
  • 46
  • 73
Wudong
  • 2,320
  • 2
  • 32
  • 46
  • Possible duplicate of http://stackoverflow.com/questions/4219197/how-to-create-a-pki-in-java – nwaltham Jan 25 '12 at 11:23
  • Thank you for the question and research later - basically, most people think in the "RSA constraints" where this cool property is not generally possible, therefore misinterpret the question... – joshis May 02 '14 at 16:29

5 Answers5

3

After some research, I have come up with the solution using Java's crypto package.

 public static void main(String[] args) {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DH");
AlgorithmParameterGenerator paramGen = AlgorithmParameterGenerator
    .getInstance("DH");
paramGen.init(1024);

// Generate the parameters
AlgorithmParameters params = paramGen.generateParameters();
DHParameterSpec dhSpec = (DHParameterSpec) params
    .getParameterSpec(DHParameterSpec.class);

keyGen.initialize(dhSpec);

KeyPair alice_key = keyGen.generateKeyPair();
KeyPair bob_key = keyGen.generateKeyPair();

SecretKey secret_alice = combine(alice_key.getPrivate(),
    bob_key.getPublic());

SecretKey secret_bob = combine(bob_key.getPrivate(),
    alice_key.getPublic());

System.out.println(Arrays.toString(secret_alice.getEncoded()));
System.out.println(Arrays.toString(secret_bob.getEncoded()));
}

private static SecretKey combine(PrivateKey private1,
    PublicKey public1)  {
KeyAgreement ka = KeyAgreement.getInstance("DH");
ka.init(private1);
ka.doPhase(public1, true);
SecretKey secretKey = ka.generateSecret("DES");
return secretKey;
}

The sysout in the end shows that alice and bob now shares a same secrete.

Wudong
  • 2,320
  • 2
  • 32
  • 46
  • I'm also trying to do this same thing, but I think this code may not be quite correct - it looks like alice_key and bob_key are initialized to the same keypair - so both "combine" to the same value. – Brad Tofel Jun 08 '13 at 05:17
2

You seem to misinterpret the article. The shared secret is not generated from the private/public key pairs. It is arbitrary data one party possesses (or generates, e.g. in the case of a key for a symmetric cipher) and shares with the other party over an insecure data transport system (e.g. E-Mail, most network protocols, etc) by means of encrypting with the other's public key and signing with the own private key. The generation algorithm of the shared secret can be arbitrary and does not depend on the private/public keys. They are just used to communicate the secret between the two parties.

flyx
  • 35,506
  • 7
  • 89
  • 126
  • hmm, I'm not so sure about this. In the article, it says the shared secret is computed offline by both parties. By offline, I assume it means no further exchange between the two parties are needed? The figure clearly shows it combines both keys to generate a shared secret. – Wudong Jan 25 '12 at 12:03
  • Look at http://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange : The extended diagram shows that the parties need to agree on a "common paint". In this case, the *final* key indeed is calculated offline. If you want to implement this algorithm, look at the example in the article. You are free to use any algorithm that fits the scheme to calculate the common keys, hence there is not *the one* way to implement this. – flyx Jan 25 '12 at 12:17
  • PS: I also think that the mention of Diffie-Hellman is a bit misleading in the Public-Key cryptography article, because it's actually a bit of a different scheme that only uses a private and no public key. You *can* use it with public an private keys, but I can't really see the point because when you're working with public and private keys, it's not necessary to calculate a shared secret. – flyx Jan 25 '12 at 12:23
1

Public and private keys are never arbitrary, but generated in conjunction, i.e. they are a key pair. Then you can use the private key to decrypt messages encryped with the public key or sign messages with the private key. The idea in Diffie-Hellman is to encrypt a symmetric key with the public key of the communication partner so it can be transmitted safely. The communication partner can decrypt the symmetric key with her private key. That way, both communication partners share a common symmetric key they can use for symmetric encyption.

There is a java package related to this, javax.crypto, but I have no experience with it. Maybe the API can help you.

joergl
  • 2,850
  • 4
  • 36
  • 42
1

Assuming my understanding is right, there should be a method combine_keys()

Sure there's way. And this way is well-known Diffie-Hellman's method. There're a lot of Java implementations of Diffie-Hellman's. For instance look here. Your combine() method is ascribed as sharedKey

Barmaley
  • 16,638
  • 18
  • 73
  • 146
0

given an arbitrary public-key and an arbitary private-key, how to generate a share-secret from it?

Assume that the party with the public key has a secret (for instance a sequence of bits generated by a cryptographically string pseudo-random number generator).

  1. It encrypts the secret using the chosen algorithm and the public key.

  2. It sends the encrypted secret to the party with the private key.

  3. The party with the private key decrypts the encrypted secret, and the two parties share the secret.

The important thing is that only the party with the private key is able to do the decryption. Thus, provided that the private key is not leaked and the algorithm is not crasked, the sequence above also guarantees that the secret is still a secret even if a third party intercepts the encrypted secret.

I'm wondering how to achieve this in Java?

There are existing implementations in Java. If you can't use one of them, then you could implement a published algorithm from scratch and use it to implement the shared secret procedure as above.

You probably need a better source of information than Wikipedia. There are textbooks on this subject ...

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216