기본 Diffie-Hellman 프로토콜을 구현하려고하는데 DES를 사용하여 보낸 값의 암호를 해독해야하는 시점까지 코드가 성공합니다. 매칭되지 않는 키의 문제가 많은 예를 살펴 보았지만 연결의 양쪽 끝에 값을 인쇄하고 있습니다. 둘 다 똑같습니다. 또한 키가 생성되는 방식을 변경하는 것은 물론 여러 패딩 방식을 시도했습니다.DES 암호화에서 올바른 패딩을 보장하려면 어떻게해야합니까?
마지막으로 암호 IvParameterSpec에 IvParameterSpec 매개 변수를 추가했지만 오류 중 하나만 해결했습니다.
소켓을 로컬 호스트에 연결하는 단일 컴퓨터에서이 컴퓨터를 실행하고 있는데 수신 된 데이터와 정확히 일치하지 않는 전송 된 데이터가있는 문제가 있는지 확인하고 있지만 전송 중에는 아무 것도 변경되지 않았습니다. 그러나 각 바이트 배열을 클라이언트 측이 패딩 (?)으로 보이는 것보다 훨씬 긴 소켓의 양쪽에 인쇄 할 때
오류가 발생했습니다. 마지막 블록은 잘못 채워집니다 때문에 해독
내 서버 코드 (의도 한대로 작동하지 않는 측) 실패 :
public static void main(String[] args) {
ServerSocket welcomeSocket = null;
// Creates a connectable socket on port 6789
try {
welcomeSocket = new ServerSocket(6789);
} catch (IOException e) {
e.printStackTrace();
}
while(true){
try{
double k2, B, A;
double n = 13;
double g = 61;
long y = 7;
B = (Math.pow(g, y))%n;
System.out.println("Accepting connections");
// Accept an incoming connection on the socket server
Socket connectionSocket = welcomeSocket.accept();
// Creates a read and write stream for that client
DataInputStream inFromClient = new DataInputStream(connectionSocket.getInputStream());
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
// Sends the double to the client
outToClient.writeDouble(B);
System.out.println("Sent " + B);
// Reads the number sent by the Client
A = inFromClient.readDouble();
System.out.println("Received " + A);
// Modifies the number
k2 = (Math.pow(A, y))%n;
System.out.println("DES key seed = " + k2);
byte[] deskeydata = toByteArray(k2);
// Turns the bytes of the modified number into a DES key spec
DESKeySpec deskeyspec = new DESKeySpec(deskeydata);
// Makes a secret key (DES)
SecretKeyFactory keyF = SecretKeyFactory.getInstance("DES");
SecretKey keystuff = keyF.generateSecret(deskeyspec);
System.out.println(keystuff.toString());
// Gets an incoming string from the client and turns it into binary
byte[] incomingBytes = new byte[128];
try{
inFromClient.readFully(incomingBytes);
} catch(EOFException eof){
System.out.println("Finished reading");
}
System.out.println(new String(incomingBytes));
Cipher c = Cipher.getInstance("DES/CBC/PKCS5Padding");
// Decrypts the string using the shared secret key
c.init(Cipher.DECRYPT_MODE, keystuff, new IvParameterSpec(new byte[8]));
byte[] ct2 = c.doFinal(incomingBytes);
// Decode it from base 64
//byte[] decodedBytes = Base64.getDecoder().decode(ct2);
// Prints the received string
System.out.println("Received: " + new String(ct2));
inFromClient.close();
outToClient.close();
} catch(Exception e){
e.printStackTrace();
}
}
}
내 고객 코드 :
public static void main(String[] args) {
// Creates a socket to the local host on port 6789
Socket clientSocket = null;
try {
clientSocket = new Socket("localhost", 6789);
} catch (IOException e1) {
e1.printStackTrace();
}
try{
double k1, B, A;
double n = 13;
double g = 61;
long x = 3;
// Sends an unencrypted number to the server
A = (Math.pow(g, x))%n;
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
DataInputStream inFromServer = new DataInputStream(clientSocket.getInputStream());
// Transforms A into a byte array and sends it over
outToServer.writeDouble(A);
outToServer.flush();
System.out.println("Sending " + A);
// Reads the incoming data from the server
B = inFromServer.readDouble();
System.out.println("Recieved " + B);
// Modifies the data to create the number for des key
k1 = (Math.pow(B, x))%n;
System.out.println("DES key seed = " + k1);
byte[] deskeydata = toByteArray(k1);
// Turns the bytes of the modified number into a DES key spec
DESKeySpec deskeyspec = new DESKeySpec(deskeydata);
// Makes a secret key (DES)
SecretKeyFactory keyF = SecretKeyFactory.getInstance("DES");
SecretKey keystuff = keyF.generateSecret(deskeyspec);
System.out.println(keystuff.toString());
// Takes in input from the user and turns it into binary
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter a message:");
String sentence = inFromUser.readLine();
byte[] str2 = sentence.getBytes();
byte[] encodedMessage = Base64.getEncoder().encode(str2);
Cipher c = Cipher.getInstance("DES/CBC/PKCS5Padding");
// Encrypts the user's input with the secret key
c.init(Cipher.ENCRYPT_MODE, keystuff, new IvParameterSpec(new byte[8]));
byte[] ct2 = c.doFinal(encodedMessage);
System.out.println("Initted the cipher and moving forward with " + new String(ct2));
// Writes the encrypted message to the user
outToServer.write(ct2);
outToServer.flush();
inFromServer.close();
outToServer.close();
} catch(Exception e){
e.printStackTrace();
}
}
을
나는이 오류를 혼자서 꽤 오랫동안 작업 해 왔기 때문에이 작업을하는 데 도움이 될 수있는 모든 것을 대단히 환영 할 것입니다.
"의도 한대로 작동하지 않는 것"보다 구체적 일 수 있습니까? 실제 오류/예기치 않은 결과는 무엇입니까? – slipperyseal
설명을 조정했습니다. 최종 블록이 올바르게 채워지지 않는다는 badpaddingexception입니다. – KM529
클라이언트 측에서 알 수없고 다양한 길이의 바이트 배열을 작성하고 있습니다. 서버 측에서는 항상 128 바이트를 읽습니다. 이러한 불일치가 버그의 원인 일 수 있습니다. 클라이언트에서 base64 인코딩과 같은 다른 버그가 있지만 서버 측에서 디코딩되지는 않습니다. –