4

私の3つの問題は次のとおりです。

  • バイトをパディングしてエラーなしで動作させる方法がわかりません:javax.crypto.BadPaddingException: Given final block not properly padded

  • NoPadding に切り替えると、8 の倍数の文字列を使用する必要があります。

  • そして最後に、そして最も重要なことは、サーバーで正しく復号化できないことです。CipherClient.javaで、ソケット経由で送信される前に復号化が機能することを証明します。

asHex を使用して、CipherServer.java が同じバイトを取得することを証明できますが、メッセージを復号化すると、正しく復号化されません。

何か不足していますか?クライアントがそれを正しく復号化する方法がわかりませんが、ストリームを通過すると、サーバーは復号化できません。

私は一日中インターネットで例を探していましたが、理解できません。誰かが何かを言う前に、私は DES を使用するのが賢明ではないことを知っていますが、これは DES が要件であるプロジェクトのためだけです。

CIPHERCLIENT.java

import java.io.*;
import java.net.*;
import java.security.*;

import javax.crypto.*;

public class CipherClient
{public static void main(String[] args) throws Exception 
{
    try {
        //Starts socket
        String host = "localhost";
        int port = 8001;
        Socket s = new Socket(host, port);

        //Generate a DES key.
        KeyGenerator keygen = KeyGenerator.getInstance("DES");
        keygen.init(56, new SecureRandom());
        SecretKey key = keygen.generateKey();           

        //Store the key in a file
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("KeyFile.xx"));
        oos.writeObject(key);
        oos.close();

        //Start Cipher Instance and cipher the message
        //Cipher c = Cipher.getInstance("DES/ECB/PKCS5Padding");            
        Cipher c = Cipher.getInstance("DES/ECB/NoPadding");
        c.init(Cipher.ENCRYPT_MODE,key);

        //Get string and encrypted version
        //String message = "The quick brown fox jumps over the lazy dog.";
        String message = "12345678";
        byte[] encryptedMsg = c.doFinal(message.getBytes("UTF-8"));

        System.out.println("Client - Message: " + message);
        System.out.println("Client - Encrypted: " + CipherServer.asHex(encryptedMsg));


        //TEST DECRYPT W/ KEY FILE W/O SERVER (WORKS!)
        //-------------------------------

        //Read key from file test
            ObjectInputStream file = new ObjectInputStream(new FileInputStream("KeyFile.xx"));
            SecretKey key2 = (SecretKey) file.readObject();
            System.out.println("Key Used: " + file.toString());
            file.close();

        //Decrypt Test
            c.init(Cipher.DECRYPT_MODE,key2);
            byte[] plainText = c.doFinal(encryptedMsg);
            System.out.println("Decrypted Message: " + new String(plainText));


        //Open stream to cipher server
        DataOutputStream os = new DataOutputStream(s.getOutputStream());
        os.writeInt(encryptedMsg.length);
        os.write(encryptedMsg);

        os.flush();
        os.close();

        //Close socket
        s.close();

    }catch (Exception e) {
        e.printStackTrace();
    }
}
 }

CIPHERSERVER.java

import java.io.*;
import java.net.*;
import java.security.NoSuchAlgorithmException;

import javax.crypto.*;


public class CipherServer
{
public static void main(String[] args) throws Exception 
{
    //Start socket server
    int port = 8001;
    ServerSocket s = new ServerSocket();
    s.setReuseAddress(true);
    s.bind(new InetSocketAddress(port));
    Socket client = s.accept();

    CipherServer server = new CipherServer();
    server.decryptMessage(client.getInputStream());

    s.close();
}


public void decryptMessage(InputStream inStream) throws IOException, NoSuchAlgorithmException
{
    try {

        //Create the Data input stream from the socket
        DataInputStream in = new DataInputStream(inStream);

        //Get the key
        ObjectInputStream file = new ObjectInputStream(new FileInputStream("KeyFile.xx"));
        SecretKey key = (SecretKey) file.readObject();
        System.out.println("Key Used: " + file.toString());
        file.close();

        //Initiate the cipher
        //Cipher d = Cipher.getInstance("DES/ECB/PKCS5Padding");                        
        Cipher d = Cipher.getInstance("DES/ECB/NoPadding");
        d.init(Cipher.DECRYPT_MODE,key);

        int len = in.readInt();
        byte[] encryptedMsg = new byte[len];
        in.readFully(encryptedMsg);         

        System.out.println("Server - Msg Length: " + len);
        System.out.println("Server - Encrypted: " + asHex(encryptedMsg));


        //String demsg = new String(d.doFinal(encryptedMsg), "UTF-8");
        //System.out.println("Decrypted Message: " + demsg);
        // -Print out the decrypt String to see if it matches the orignal message.
        byte[] plainText = d.doFinal(encryptedMsg);
        System.out.println("Decrypted Message: " + new String(plainText, "UTF-8"));


    } catch (Exception e) {
        e.printStackTrace();
    }
}

//Function to make the bytes printable (hex format)
public static String asHex(byte buf[]) {
    StringBuilder strbuf = new StringBuilder(buf.length * 2);
    int i;
    for (i = 0; i < buf.length; i++) {
        if (((int) buf[i] & 0xff) < 0x10) {
            strbuf.append("0");
        }
        strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
    }
    return strbuf.toString();
}
 }
4

2 に答える 2

1

キーファイルを作成する前にサーバーへのソケットを作成すると、サーバーは最後の実行からキーを適切に読み取ります。

Socket s = new Socket(host, port);キー ファイルを閉じた後、 を移動してみてください。

イベントは次のとおりです。

    Client                 Server
    -----------------      ------------------
    Connect to server
                           Accept connection
                           Read key file
                           (block on receive)
    Generate Key
    Write Key File
    Send message
                           Receive message
    etc.
于 2013-11-14T02:30:18.830 に答える
0

コードを見ると、キーが正しくないとしか思えません。間違ったフォルダなどを使用している可能性があります。BadPaddingException通常、パディングが正しくない場合、データの最後のブロックが破損している場合、または間違ったキーを使用している場合にのみ発生します。デバッガーを使用SecretKey.getEncoded()するか、キーが 16 進エンコーダーと一緒にあるかどうかを確認することができます。

于 2013-11-11T21:32:38.673 に答える