2016-04-01 9 views
1

私は多くの研究を行ってきましたが、この問題の解決策を見つけることはできません。私は何時間も費やしてしまったので、私はそれを理解することができないので、私よりも経験豊富な誰かが助けてくれることを願っています。このプログラムはベストプラクティスではないかもしれませんが、割り当てのためのものです。Diffie-Hellmanキーオーバーソケット受信エラー

RSAを使用して公開鍵を送信していますが、もっと重要なのはBob(サーバー)からDice HellmanパラメータをAlice(クライアント)に送信しようとしていることです。スレッド内

例外「メイン」java.security.spec.InvalidKeySpecException: com.sun.crypto.provider.DHKeyFactory.engineGeneratePublicで 不適切な鍵仕様(DHKeyFactoryプログラムを実行しているとき、私は次のエラーを取得しています.java:85) java.security.InvalidKeyException:キーエンコーディングの解析中にエラーが発生しました。 com.sun.crypto.provider.DHPublicKey。(DHPublicKey.java:178)at com.sun.crypto.provider.DHKeyFactory.engineGeneratePublic(DHKeyFactory.java:78) ... 2より原因:java.io.IOException: DerInputStream.getLength():lengthTag = 127が大きすぎます。 sun.security.util.DerInputStream.getLength(DerInputStream.java:561) at sun.security.util.DerValue.init(DerValue.java:365)at sun.security.util.DerValue。(DerValue.java : com.sun.crypto.provider.DHPublicKeyで320)(DHPublicKey.java:125)...ここでは3以上

コードである:。 Client.java:

package client; 
import java.io.*; 
import java.security.*; 
import javax.crypto.*; 
import java.util.*; 
import java.net.*; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import javax.crypto.spec.DHParameterSpec; 
import java.security.spec.*; 


class Client{ 
    private static PublicKey publicKey = null; 
    private static PrivateKey privateKey = null; 
    private static PublicKey rsaBobPub = null; 
    private static SecretKey SecretSharedKeyCipher = null; 
    private static SecretKey SecretSharedKeyIntgSend = null; 
    private static SecretKey SecretSharedKeyIntRecv = null; 
    private static KeyAgreement aKeyAgreement = null; 


    public static void main(String args[]) throws ClassNotFoundException, `IOException, NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidParameterSpecException, InvalidKeySpecException{` 
     Client client = new Client(); 
     KeyPairGenerator keyGen; 
     byte[] alicePub; 
     Cipher cipher2; 
     byte[] encryptedDH = null; 
     byte[] bobEncryptedDH = null; 
     OutputStream dh; 
     InputStream bobDHConn; 

      Socket connection = new Socket("localhost", 4129); 

      //Generate Keys & then send to Bob 
       keyGen = KeyPairGenerator.getInstance("RSA"); 
       keyGen.initialize(2048); 
       KeyPair keyPair = keyGen.genKeyPair(); 
       publicKey = keyPair.getPublic(); 
       privateKey = keyPair.getPrivate(); 

      //Send Public Key to Bob 
       ObjectOutputStream toBob = new ObjectOutputStream(connection.getOutputStream()); 
       toBob.writeObject(publicKey); 

      //Receive Bob's Public Key 
       ObjectInputStream fromBob; 
       fromBob = new ObjectInputStream(connection.getInputStream()); 
       rsaBobPub = (PublicKey) fromBob.readObject(); 

    //SET UP DIFFIE HELLMAN PROTOCOL 
    //For some reason, when receiving Bob's DH param, I am getting a lot of issues. 
      //Exchange DH info 
       DHParameterSpec paramSpec; 
       AlgorithmParameterGenerator paramGen = AlgorithmParameterGenerator.getInstance("DH"); 
       paramGen.init(512); 
       AlgorithmParameters parameters = paramGen.generateParameters(); 
       paramSpec = (DHParameterSpec) parameters.getParameterSpec(DHParameterSpec.class); 

      //Generate Key Pair 
       KeyPairGenerator aliceKpGen = KeyPairGenerator.getInstance("DH"); 
       aliceKpGen.initialize(paramSpec); 
       KeyPair aliceKp = aliceKpGen.generateKeyPair(); 
       aKeyAgreement = KeyAgreement.getInstance("DH"); 
       aKeyAgreement.init(aliceKp.getPrivate()); 
       alicePub = aliceKp.getPublic().getEncoded(); 
       //System.out.println(aliceKp.getPublic()) 
       //System.out.println(aliceKp.getPublic().getEncoded()) 
       //Send Alice's encrypted DH byte info to Bob 
       /*  cipher2 = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
        cipher2.init(Cipher.ENCRYPT_MODE, rsaBobPub); 
        encryptedDH = cipher2.doFinal(alicePub); 
        System.out.print(encryptedDH); 
       */ 
        dh = connection.getOutputStream(); 
        dh.write(alicePub); 

      //Recieve Bob's DH Info 
       bobDHConn = connection.getInputStream(); 
       int length; 
       byte[] bobDH = null; 


       while((length = bobDHConn.available()) == 0){ 
        bobDH = new byte[length]; 
        int i = 0; 
        while(i < length){ 
         i+= bobDHConn.read(bobDH, i, length - i); 
        } 
       } 
      //NOT WORKING 
      KeyFactory clientKeyFac = KeyFactory.getInstance("DH"); 
      X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(bobDH); 
      PublicKey bobsDHPubKey = clientKeyFac.generatePublic(x509KeySpec); 
      aKeyAgreement.doPhase(bobsDHPubKey, true); 


     //Generate AES Secret Keys 
     SecretKey aesKeyGen = aKeyAgreement.generateSecret("AES"); 


    } 
} 

Server.java

package server; 
import java.io.*; 
import java.security.*; 
import javax.crypto.*; 
import java.util.*; 
import java.net.*; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.security.spec.InvalidKeySpecException; 
import java.security.spec.X509EncodedKeySpec; 
import javax.crypto.interfaces.DHPublicKey; 
import javax.crypto.spec.DHParameterSpec; 

public class Server{ 
    private static int port = 4129; 
    private static PublicKey publicKey = null; 
    private static PrivateKey privateKey = null; 
    private static PublicKey rsaAlicePub = null; 
    private static ServerSocket server = null; 
    private static SecretKey SecretSharedKeyCipher = null; 
    private static SecretKey SecretSharedKeyIntgSend = null; 
    private static SecretKey SecretSharedKeyIntRecv = null; 

    public static void main(String args[]) throws ClassNotFoundException, NoSuchAlgorithmException, IOException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidKeySpecException, InvalidAlgorithmParameterException{ 
     //Declarations 
      Server serv = new Server(); 
      server = new ServerSocket(4129); 
      server.setReuseAddress(true); 
      KeyPairGenerator keyGen; 
      byte[] cipherText = null; 
      InputStream input = null; 
      byte[] data = null; 
      byte[] decryptedDH; 
      InputStream DH = null; 
      byte[] DHinfo = null; 
      int length; 
      byte[] aliceEncryptedDH = null;  
      SecretKey keyGenDH= null; 
      InputStream aliceDH = null; 
      Cipher cipher; 
      PublicKey bobDHPub = null; 
      OutputStream sendDH; 

      //String message = "bbbbbbbbbbbbbb"; 
      String message = "bbbbbbb"; 
      Socket client = server.accept(); 

      //Get Public Key froM Alice 
       ObjectInputStream alicePK; 
       alicePK = new ObjectInputStream(client.getInputStream()); 
       rsaAlicePub = (PublicKey)alicePK.readObject(); 

      //Generate Bob's keys 
       keyGen = KeyPairGenerator.getInstance("RSA"); 
       keyGen.initialize(2048); 
       KeyPair keyPair = keyGen.genKeyPair(); 
       privateKey = keyPair.getPrivate(); 
       publicKey = keyPair.getPublic(); 

      //Send Bob's public Key to Alice 
       ObjectOutputStream bobPK; 
       bobPK = new ObjectOutputStream(client.getOutputStream()); 
       bobPK.writeObject(publicKey); 

      //Exchange information for DH 
      //Decrypt received information using Bob PK 
      //You can assume that Bob selects the public parameters of Diffie‐Hellman protocol, and send them to Alice 

      DH = client.getInputStream(); 
      while((length = DH.available()) == 0); 
      int i = 0; 
      DHinfo = new byte[length]; 
      while (i < length) { 
       i += DH.read(DHinfo, i, length - i); 
      } 
/* 
      cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
      cipher.init(Cipher.DECRYPT_MODE, privateKey); 
      decryptedDH = cipher.doFinal(DHinfo); 
      */ 
      KeyFactory clientKeyFac = KeyFactory.getInstance("DH"); 
      X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(DHinfo); 
      bobDHPub = clientKeyFac.generatePublic(x509KeySpec); 

      DHParameterSpec dhParamSpec = ((DHPublicKey) bobDHPub).getParams(); 

      //Create Bob DH Keys 
       KeyPairGenerator bobKpGen = KeyPairGenerator.getInstance("DH"); 
       bobKpGen.initialize(dhParamSpec); 
       KeyPair bobsKeys = bobKpGen.generateKeyPair(); 

       KeyAgreement bobKeyAgreement = KeyAgreement.getInstance("DH"); 
       bobKeyAgreement.init(bobsKeys.getPrivate()); 
       bobKeyAgreement.doPhase(bobDHPub, true); 

      //Send Bob's DH Parameters to Alice 
      //send bobsKeys.getPublic().getEncoded() 
        sendDH = client.getOutputStream(); 
        sendDH.write(bobsKeys.getPublic().getEncoded()); 

      //Encrypt message.getBytes(); 

    } 

    private void Server() throws IOException{ 
     server = new ServerSocket(port); 


    } 



} 
+0

はい方程式の外にソケットを入れたらうまくいきますか?言い換えれば、DHキーの両方のセットを生成し、それ自身の内部で交換を行う単一のプログラムを書くと、それは機能しますか? – QuantumMechanic

答えて

2

あなたのInputStreamからの読み方が間違っています。まず、利用可能なメソッドを使用する必要はありません。それはあなたが返すと思うものを返さないし、返すものはあなたにとって有用ではありません。

OutputStreamにバイト配列を書き込んで、もう一方の側で同じバイト配列を再構築したい場合は、バイト配列の長さを何らかの形で相手側に伝える必要があります。最も簡単な方法は、長さを接頭辞として付けることです。

あなたの場合は、すでにRaw出力および入力ストリームにObjectOutputStreamおよびObjectInputStreamがラップされています。ちょうどそれらを使用します。バイト配列もオブジェクトなので、転送するにはwriteObjectreadObjectを呼び出すことができます。クライアントで

toBob.writeObject(alicePub); 

およびサーバーで:

DHinfo = (byte[]) alicePK.readObject(); 

(注:複数の目的のためにそれを使用する場合はfromAliceのようなものにalicePkの名前を変更する必要があります)

関連する問題