2014-01-12 60 views
7

我正在开发一个Java个人项目,它涉及通过不安全的渠道发送敏感数据。我需要知道如何使用它的库在java中实现Diffie Hellman密钥交换(DHKE)。我知道所有关于它的密码理论,所以不需要详细说明,我只需要一个非常基本的实现,所以我有两个程序共享一个密钥。我从java2s.com得到了这个例子,但它并不完整:Java中的Diffie-Hellman密钥交换

import java.math.BigInteger; 
import java.security.KeyFactory; 
import java.security.KeyPair; 
import java.security.KeyPairGenerator; 
import java.security.SecureRandom; 

import javax.crypto.spec.DHParameterSpec; 
import javax.crypto.spec.DHPublicKeySpec; 

public class Main { 
    public final static int pValue = 47; 

    public final static int gValue = 71; 

    public final static int XaValue = 9; 

    public final static int XbValue = 14; 

    public static void main(String[] args) throws Exception { 
    BigInteger p = new BigInteger(Integer.toString(pValue)); 
    BigInteger g = new BigInteger(Integer.toString(gValue)); 
    BigInteger Xa = new BigInteger(Integer.toString(XaValue)); 
    BigInteger Xb = new BigInteger(Integer.toString(XbValue)); 

    int bitLength = 512; // 512 bits 
    SecureRandom rnd = new SecureRandom(); 
    p = BigInteger.probablePrime(bitLength, rnd); 
    g = BigInteger.probablePrime(bitLength, rnd); 

    createSpecificKey(p, g); 
    } 

    public static void createSpecificKey(BigInteger p, BigInteger g) throws Exception { 
    KeyPairGenerator kpg = KeyPairGenerator.getInstance("DiffieHellman"); 

    DHParameterSpec param = new DHParameterSpec(p, g); 
    kpg.initialize(param); 
    KeyPair kp = kpg.generateKeyPair(); 

    KeyFactory kfactory = KeyFactory.getInstance("DiffieHellman"); 

    DHPublicKeySpec kspec = (DHPublicKeySpec) kfactory.getKeySpec(kp.getPublic(), 
     DHPublicKeySpec.class); 
    } 
} 

我该如何继续呢?任何人都可以帮我完成剩下的代码吗?

回答

1

这里有一个工作例如:

static void main() { 

    DH dh = new DH(); 
    byte[] myPublicKey = dh.generatePublicKey(); 

    /* Send myPublicKey to other party, and get hisPublicKey in return */ 

    byte[] sharedKey = dh.computeSharedKey(hisPublicKey) 
    /* sharedKey is now 'shared' between both parties */ 

} 

public class DH { 

    private static final String TAG = "DH"; 

    private KeyPair keyPair; 
    private KeyAgreement keyAgree; 

    public byte[] generatePublicKey() { 
     DHParameterSpec dhParamSpec; 

     try { 
      dhParamSpec = new DHParameterSpec(P, G); 
      Log.i(TAG, "P = " + P.toString(16)); 
      KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("DiffieHellman"); 
      keyPairGen.initialize(dhParamSpec); 
      keyPair = keyPairGen.generateKeyPair(); 
      Log.i(TAG, "Y = " + ((DHPublicKey) keyPair.getPublic()).getY().toString(16)); 
      keyAgree = KeyAgreement.getInstance("DiffieHellman"); 
      keyAgree.init(keyPair.getPrivate()); 

      BigInteger pubKeyBI = ((DHPublicKey) keyPair.getPublic()).getY(); 
      byte[] pubKeyBytes = pubKeyBI.toByteArray(); 
      Log.i(TAG, String.format(TAG, "Y [%d] = %s", pubKeyBytes.length, Utils.toHexString(pubKeyBytes))); 
      return pubKeyBytes; 
     } catch (Exception e) { 
      Log.e(TAG, "generatePubKey(): " + e.getMessage()); 
      return null; 
     } 
    } 

    public byte[] computeSharedKey(byte[] pubKeyBytes) { 
     if (keyAgree == null) { 
      Log.e(TAG, "computeSharedKey(): keyAgree IS NULL!!"); 
      return null; 
     } 

     try { 
      KeyFactory keyFactory = KeyFactory.getInstance("DiffieHellman"); 
      BigInteger pubKeyBI = new BigInteger(1, pubKeyBytes); 
      Log.i(TAG, "Y = " + pubKeyBI.toString(16)); 
      PublicKey pubKey = keyFactory.generatePublic(new DHPublicKeySpec(pubKeyBI, P, G)); 
      keyAgree.doPhase(pubKey, true); 
      byte[] sharedKeyBytes = keyAgree.generateSecret(); 
      Log.i(TAG, String.format("SHARED KEY[%d] = %s", sharedKeyBytes.length, Utils.toHexString(sharedKeyBytes))); 
      return sharedKeyBytes; 
     } catch (Exception e) { 
      Log.e(TAG, "computeSharedKey(): " + e.getMessage()); 
      return null; 
     } 
    } 

    private static final byte P_BYTES[] = { 
      (byte)0xF4, (byte)0x88, (byte)0xFD, (byte)0x58, 
      ... 
      (byte)0xE9, (byte)0x2F, (byte)0x78, (byte)0xC7 
    }; 
    private static final BigInteger P = new BigInteger(1, P_BYTES); 

    private static final BigInteger G = BigInteger.valueOf(2); 
} 
0

下面的代码使用椭圆曲线的Diffie-Hellman生成并分享128位加密密钥和AES。

import sun.misc.BASE64Decoder; 
import sun.misc.BASE64Encoder; 

import javax.crypto.*; 
import javax.crypto.spec.SecretKeySpec; 
import java.io.IOException; 
import java.security.*; 

public class AESSecurityCap { 

private PublicKey publickey; 
KeyAgreement keyAgreement; 
byte[] sharedsecret; 

String ALGO = "AES"; 

AESSecurityCap() { 
    makeKeyExchangeParams(); 
} 

private void makeKeyExchangeParams() { 
    KeyPairGenerator kpg = null; 
    try { 
     kpg = KeyPairGenerator.getInstance("EC"); 
     kpg.initialize(128); 
     KeyPair kp = kpg.generateKeyPair(); 
     publickey = kp.getPublic(); 
     keyAgreement = KeyAgreement.getInstance("ECDH"); 
     keyAgreement.init(kp.getPrivate()); 

    } catch (NoSuchAlgorithmException | InvalidKeyException e) { 
     e.printStackTrace(); 
    } 
} 

public void setReceiverPublicKey(PublicKey publickey) { 
    try { 
     keyAgreement.doPhase(publickey, true); 
     sharedsecret = keyAgreement.generateSecret(); 
    } catch (InvalidKeyException e) { 
     e.printStackTrace(); 
    } 
} 

public String encrypt(String msg) { 
    try { 
     Key key = generateKey(); 
     Cipher c = Cipher.getInstance(ALGO); 
     c.init(Cipher.ENCRYPT_MODE, key); 
     byte[] encVal = c.doFinal(msg.getBytes()); 
     return new BASE64Encoder().encode(encVal); 
    } catch (BadPaddingException | InvalidKeyException | NoSuchPaddingException | IllegalBlockSizeException | NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } 
    return msg; 
} 

public String decrypt(String encryptedData) { 
    try { 
     Key key = generateKey(); 
     Cipher c = Cipher.getInstance(ALGO); 
     c.init(Cipher.DECRYPT_MODE, key); 
     byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData); 
     byte[] decValue = c.doFinal(decordedValue); 
     return new String(decValue); 
    } catch (BadPaddingException | InvalidKeyException | NoSuchPaddingException | IllegalBlockSizeException | NoSuchAlgorithmException | IOException e) { 
     e.printStackTrace(); 
    } 
    return encryptedData; 
} 

public PublicKey getPublickey() { 
    return publickey; 
} 

protected Key generateKey() { 
    return new SecretKeySpec(sharedsecret, ALGO); 
} 
} 

扩展自己的类添加AES加密功能

public class Node extends AESSecurityCap { 

//your class 

} 

最后,方式使用加密

public class Main { 

public static void main(String[] args) throws IOException { 
    Node server = new Node(); 
    Node client = new Node(); 

    server.setReceiverPublicKey(client.getPublickey()); 

    client.setReceiverPublicKey(server.getPublickey()); 

    String data = "hello"; 

    String enc = server.encrypt(data); 

    System.out.println("hello is coverted to "+enc); 

    System.out.println(enc+" is converted to "+client.decrypt(enc)); 

} 
} 

输出:

hello is coverted to OugbNvUuylvAr9mKv//nLA== 
OugbNvUuylvAr9mKv//nLA== is converted to hello 

Process finished with exit code 0