2012-01-25 18 views
6

estoy leyendo la wikipedia sobre criptografía de clave pública de clave pública (http://en.wikipedia.org/wiki/Public-key_cryptography) y en ella se dice:¿Cómo combinar una clave privada y una clave pública de un secreto compartido en Java

En el Esquema de intercambio de claves de Diffie-Hellman, cada parte genera un par de claves público/privado y distribuye la clave pública ... Después de obtener una copia auténtica de las claves públicas de los demás, Alice y Bob pueden calcular un secreto compartido sin conexión. El secreto compartido se puede usar, por ejemplo, como la clave para un cifrado simétrico.

Me pregunto cómo lograr esto en Java? es decir, dada una clave pública arbitraria y una clave privada arbitraria, ¿cómo generar un secreto compartido de ella?

Para hacerlo más claro:

Alice tiene un par de claves pública/privada key_pair_alice,

Bob tiene un par de claves pública/privada key_pair_bob,

Asumiendo mi entendimiento es bien, debe haber un método combine_keys() para que:

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

Mi pregunta es cómo implementar el método combine_keys() en Java.

Gracias.

+0

Posible duplicado de http://stackoverflow.com/questions/4219197/how-to-create-a-pki-in-java – nwaltham

+0

Gracias por la pregunta y la investigación posterior, básicamente, la mayoría de la gente piensa en el "RSA" restricciones "donde esta buena propiedad no es generalmente posible, por lo tanto, malinterpretar la pregunta ... – joshis

Respuesta

3

Después de algunas investigaciones, he encontrado la solución usando el paquete crypto de Java.

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; 
} 

El sysout al final muestra que alice y bob ahora comparten un mismo secreto.

+0

También trato de hacer lo mismo, pero creo que este código puede no ser del todo correcto, parece que alice_key y bob_key se inicializan en el mismo par de claves, por lo que ambos se "combinan" con el mismo valor. –

2

Parece que malinterpretas el artículo. El secreto compartido no se genera a partir de los pares de claves privadas/públicas. Son datos arbitrarios que una parte posee (o genera, por ejemplo, en el caso de una clave para un cifrado simétrico) y comparte con la otra parte un sistema de transporte de datos inseguro (por ejemplo, correo electrónico, la mayoría de protocolos de red, etc.) mediante encriptar con la clave pública del otro y firmar con la clave privada propia. El algoritmo de generación del secreto compartido puede ser arbitrario y no depende de las claves privadas/públicas. Solo se usan para comunicar el secreto entre las dos partes.

+0

hmm, no estoy tan seguro de esto. En el artículo, dice que el secreto compartido se calcula fuera de línea por ambas partes. Por fuera de línea, supongo que significa que no se necesita más intercambio entre las dos partes? La figura muestra claramente que combina ambas claves para generar un secreto compartido. – Wudong

+0

Mire http://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange: El diagrama extendido muestra que las partes deben ponerse de acuerdo sobre una "pintura común". En este caso, la clave * final * se calcula sin conexión. Si desea implementar este algoritmo, mire el ejemplo en el artículo. Usted es libre de usar cualquier algoritmo que se ajuste al esquema para calcular las claves comunes, por lo tanto, no hay * la única * forma de implementar esto. – flyx

+0

PD: También creo que la mención de Diffie-Hellman es un poco engañosa en el artículo de criptografía Public-Key, porque en realidad es un esquema diferente que solo usa una clave privada y ninguna pública. * Puedes * usarlo con claves públicas y privadas, pero no puedo ver el punto porque cuando trabajas con claves públicas y privadas, no es necesario calcular un secreto compartido. – flyx

1

Las claves públicas y privadas nunca son arbitrarias, sino que se generan juntas, es decir, son un par de claves. Luego puede usar la clave privada para descifrar los mensajes encriptados con la clave pública o los mensajes de firma con la clave privada. La idea en Diffie-Hellman es encriptar una clave simétrica con la clave pública del compañero de comunicación para que pueda transmitirse de manera segura. El compañero de comunicación puede descifrar la clave simétrica con su clave privada. De esta forma, ambos socios de comunicación comparten una clave simétrica común que pueden usar para la encriptación simétrica.

Hay un paquete de java relacionado con esto, javax.crypto, pero no tengo experiencia con él. Tal vez la API puede ayudarte.

0

dado una clave pública arbitraria y una clave privada arbitraria, cómo generar un secreto compartido de ella?

Supongamos que la parte con la clave pública tiene un secreto (por ejemplo, una secuencia de bits generados por un generador de números pseudoaleatorios de cadena criptográfica).

  1. Encripta el secreto utilizando el algoritmo elegido y la clave pública.

  2. Envía el secreto encriptado a la parte con la clave privada.

  3. La parte con la clave privada descifra el secreto encriptado, y las dos partes comparten el secreto.

Lo importante es que sólo el partido con la clave privada es capaz para hacer el descifrado. Por lo tanto, siempre que la clave privada no se filtre y el algoritmo no se bloquee, la secuencia anterior también garantiza que el secreto sigue siendo secreto incluso si un tercero intercepta el secreto cifrado.

Me pregunto cómo lograr esto en Java?

Existen implementaciones existentes en Java. Si no puede usar uno de ellos, puede implementar un algoritmo publicado desde cero y usarlo para implementar el procedimiento secreto compartido como se indicó anteriormente.

Probablemente necesite una mejor fuente de información que Wikipedia. Hay libros de texto sobre este tema ...

1

Suponiendo que mi entendimiento es correcto, no debería ser un método combine_keys()

seguro de que hay manera. Y de esta manera es bien conocido Diffie-Hellman's method. Hay muchas implementaciones Java de Diffie-Hellman's. Por ejemplo, look here. Su método combine() se asigna como sharedKey

Cuestiones relacionadas