change key exchange to ED25519
This commit is contained in:
parent
256721aa12
commit
6afc26e601
11 changed files with 148 additions and 105 deletions
|
@ -97,7 +97,7 @@ public class GuiServer extends Gui implements FieldCallback {
|
|||
if(GuiServer.this.keypair == null) {
|
||||
GuiServer.this.keypair = EncryptUtil.createKeypair();
|
||||
GuiServer.this.keyDigest = EncryptUtil.getXorSha512Hash(GuiServer.this.keypair.getPublic().getEncoded());
|
||||
GuiServer.this.keyLabel.setText("Anmelde-Pubkey: RSA-4096 " + GuiServer.this.keyDigest);
|
||||
GuiServer.this.keyLabel.setText("Anmelde-Pubkey: " + EncryptUtil.KEY_ALGO_DISPLAY + " " + GuiServer.this.keyDigest);
|
||||
GuiServer.this.keyButton.setText("Schlüsselpaar entfernen");
|
||||
GuiServer.this.passLabel.setText("Ersatz-Passwort (mind. 8 Zeichen)");
|
||||
GuiServer.this.copyKeyButton.enabled = true;
|
||||
|
@ -124,7 +124,7 @@ public class GuiServer extends Gui implements FieldCallback {
|
|||
GuiServer.this.encToggle.setValue(reqEnc);
|
||||
GuiServer.this.serverKey = key;
|
||||
GuiServer.this.serverDigest = sdigest;
|
||||
GuiServer.this.idLabel.setText("Server-Pubkey: " + (key != null ? "RSA-4096 " + GuiServer.this.serverDigest : "nicht vorhanden"));
|
||||
GuiServer.this.idLabel.setText("Server-Pubkey: " + (key != null ? EncryptUtil.KEY_ALGO_DISPLAY + " " + GuiServer.this.serverDigest : "nicht vorhanden"));
|
||||
GuiServer.this.resetButton.enabled = key != null;
|
||||
GuiServer.this.copyIdButton.enabled = key != null;
|
||||
GuiServer.this.copyKeyButton.enabled = !confirmed;
|
||||
|
@ -138,7 +138,7 @@ public class GuiServer extends Gui implements FieldCallback {
|
|||
else {
|
||||
GuiServer.this.keypair = keys;
|
||||
GuiServer.this.keyDigest = digest;
|
||||
GuiServer.this.keyLabel.setText("Anmelde-Pubkey: RSA-4096 " + GuiServer.this.keyDigest);
|
||||
GuiServer.this.keyLabel.setText("Anmelde-Pubkey: " + EncryptUtil.KEY_ALGO_DISPLAY + " " + GuiServer.this.keyDigest);
|
||||
GuiServer.this.keyButton.setText("Schlüsselpaar entfernen");
|
||||
GuiServer.this.passLabel.setText("Ersatz-Passwort (mind. 8 Zeichen)");
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ public class GuiServer extends Gui implements FieldCallback {
|
|||
}
|
||||
}, "Kopieren"));
|
||||
this.copyKeyButton.enabled = this.keypair != null;
|
||||
this.keyLabel = this.add(new Label(0, 102, 480, "Anmelde-Pubkey: " + (this.keypair != null ? "RSA-4096 " + this.keyDigest : "nicht vorhanden"), true));
|
||||
this.keyLabel = this.add(new Label(0, 102, 480, "Anmelde-Pubkey: " + (this.keypair != null ? EncryptUtil.KEY_ALGO_DISPLAY + " " + this.keyDigest : "nicht vorhanden"), true));
|
||||
this.encToggle = this.add(new Toggle(0, 190, 480, 0, false, this.server.requiresEncryption(), null, "Nur Verschlüsselte Verbindung akzeptieren"));
|
||||
this.serverKey = this.server.getServerKey();
|
||||
this.serverDigest = this.serverKey == null ? null : EncryptUtil.getXorSha512Hash(this.serverKey.getEncoded());
|
||||
|
@ -177,7 +177,7 @@ public class GuiServer extends Gui implements FieldCallback {
|
|||
}
|
||||
}, "Kopieren"));
|
||||
this.copyIdButton.enabled = this.serverKey != null;
|
||||
this.idLabel = this.add(new Label(0, 224, 480, "Server-Pubkey: " + (this.serverKey != null ? "RSA-4096 " + this.serverDigest : "nicht vorhanden"), true));
|
||||
this.idLabel = this.add(new Label(0, 224, 480, "Server-Pubkey: " + (this.serverKey != null ? EncryptUtil.KEY_ALGO_DISPLAY + " " + this.serverDigest : "nicht vorhanden"), true));
|
||||
}
|
||||
this.shift();
|
||||
}
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
package client.network;
|
||||
|
||||
import java.security.KeyPair;
|
||||
import java.security.PublicKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
import client.Client;
|
||||
import client.gui.GuiConfirm;
|
||||
import client.gui.GuiConnect;
|
||||
|
@ -41,6 +39,7 @@ public class ClientLoginHandler implements IClientLoginHandler {
|
|||
private final Client gm;
|
||||
private final NetConnection connection;
|
||||
private final ServerInfo server;
|
||||
private final KeyPair tempKeys;
|
||||
|
||||
private LoginState state = LoginState.HANDSHAKE;
|
||||
private byte[] token;
|
||||
|
@ -49,6 +48,7 @@ public class ClientLoginHandler implements IClientLoginHandler {
|
|||
this.connection = conn;
|
||||
this.gm = gm;
|
||||
this.server = server;
|
||||
this.tempKeys = EncryptUtil.createDHKeypair();
|
||||
}
|
||||
|
||||
public void onDisconnect(String reason)
|
||||
|
@ -67,9 +67,8 @@ public class ClientLoginHandler implements IClientLoginHandler {
|
|||
return;
|
||||
}
|
||||
this.connection.setConnectionState(PacketRegistry.LOGIN);
|
||||
final SecretKey secret = EncryptUtil.createSharedKey();
|
||||
final PublicKey pubkey = packet.getKey();
|
||||
final byte[] token = packet.getToken();
|
||||
final PublicKey tempKey = packet.getTempKey();
|
||||
if(this.server.getServerKey() == null) {
|
||||
this.state = LoginState.CONFIRMING;
|
||||
this.gm.schedule(new Runnable() {
|
||||
|
@ -80,33 +79,33 @@ public class ClientLoginHandler implements IClientLoginHandler {
|
|||
ClientLoginHandler.this.server.setServerKey(pubkey);
|
||||
GuiConnect.INSTANCE.editServer(ClientLoginHandler.this.server);
|
||||
ClientLoginHandler.this.gm.displayConnecting(ClientLoginHandler.this.server);
|
||||
ClientLoginHandler.this.startEncryption(secret, pubkey, token);
|
||||
ClientLoginHandler.this.startEncryption(tempKey);
|
||||
}
|
||||
else {
|
||||
ClientLoginHandler.this.connection.closeChannel("Verbindung wurde abgebrochen");
|
||||
}
|
||||
}
|
||||
}, "Die Identität des Servers ist unbekannt", "Es wurde noch nie mit diesem Server verbunden.\nSoll die Verbindung wirklich fortgesetzt werden?\n\nDie Pubkey-ID des Servers lautet:\nRSA-4096 " + EncryptUtil.getXorSha512Hash(pubkey.getEncoded()) + "\n\nDer öffentliche Schlüssel des Servers lautet:\n" + Util.breakString(Base64.getEncoder().encodeToString(pubkey.getEncoded()), 64), "Verbindung herstellen", "Abbrechen und trennen"));
|
||||
}, "Die Identität des Servers ist unbekannt", "Es wurde noch nie mit diesem Server verbunden.\nSoll die Verbindung wirklich fortgesetzt werden?\n\nDie Pubkey-ID des Servers lautet:\n" + EncryptUtil.KEY_ALGO_DISPLAY + " " + EncryptUtil.getXorSha512Hash(pubkey.getEncoded()) + "\n\nDer öffentliche Schlüssel des Servers lautet:\n" + Util.breakString(Base64.getEncoder().encodeToString(pubkey.getEncoded()), 64), "Verbindung herstellen", "Abbrechen und trennen"));
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
else if(!this.server.getServerKey().equals(pubkey)) {
|
||||
this.connection.closeChannel("Die Identität des Servers hat sich geändert\n\nDer Server hat einen anderen öffentlichen Schlüssel als vorher bekannt war,\ndies kann bedeuten dass der Inhaber jetzt einen anderen Schlüssel verwendet\noder sich ein anderer Server als dieser ausgibt (\"Man-in-the-middle-attack\").\n\nDie Pubkey-ID des Servers lautet: RSA-4096 " + EncryptUtil.getXorSha512Hash(pubkey.getEncoded()) + "\n\nDer öffentliche Schlüssel des Servers lautet:\n" + Util.breakString(Base64.getEncoder().encodeToString(pubkey.getEncoded()), 64) + "\n\nDie vertrauenswürdige Pubkey-ID lautet: RSA-4096 " + EncryptUtil.getXorSha512Hash(this.server.getServerKey().getEncoded()) +
|
||||
this.connection.closeChannel("Die Identität des Servers hat sich geändert\n\nDer Server hat einen anderen öffentlichen Schlüssel als vorher bekannt war,\ndies kann bedeuten dass der Inhaber jetzt einen anderen Schlüssel verwendet\noder sich ein anderer Server als dieser ausgibt (\"Man-in-the-middle-attack\").\n\nDie Pubkey-ID des Servers lautet: " + EncryptUtil.KEY_ALGO_DISPLAY + " " + EncryptUtil.getXorSha512Hash(pubkey.getEncoded()) + "\n\nDer öffentliche Schlüssel des Servers lautet:\n" + Util.breakString(Base64.getEncoder().encodeToString(pubkey.getEncoded()), 64) + "\n\nDie vertrauenswürdige Pubkey-ID lautet: " + EncryptUtil.KEY_ALGO_DISPLAY + " " + EncryptUtil.getXorSha512Hash(this.server.getServerKey().getEncoded()) +
|
||||
"\n\nFalls der Server trotzdem vertrauenswürdig wirkt, kann die Server-Identifizierung\nin den Einstellungen von '" + this.server.getName() + "' zurückgesetzt werden.");
|
||||
return;
|
||||
}
|
||||
this.startEncryption(secret, pubkey, token);
|
||||
this.startEncryption(tempKey);
|
||||
}
|
||||
|
||||
private void startEncryption(SecretKey secret, PublicKey pubkey, byte[] token) {
|
||||
private void startEncryption(PublicKey serverKey) {
|
||||
this.state = LoginState.CHALLENGE;
|
||||
this.connection.sendPacket(new LPacketStartEncrypt(secret, pubkey, token), new GenericFutureListener < Future <? super Void >> () {
|
||||
this.connection.sendPacket(new LPacketStartEncrypt(this.tempKeys.getPublic()), new GenericFutureListener < Future <? super Void >> () {
|
||||
public void operationComplete(Future <? super Void > u) throws Exception {
|
||||
ClientLoginHandler.this.connection.startEncryption(secret);
|
||||
ClientLoginHandler.this.connection.startEncryption(EncryptUtil.makeKeyAgreement(ClientLoginHandler.this.tempKeys.getPrivate(), serverKey));
|
||||
ClientLoginHandler.this.token = new byte[32];
|
||||
TOKEN_RNG.nextBytes(ClientLoginHandler.this.token);
|
||||
ClientLoginHandler.this.connection.sendPacket(new LPacketChallenge(pubkey, ClientLoginHandler.this.token));
|
||||
ClientLoginHandler.this.connection.sendPacket(new LPacketChallenge(ClientLoginHandler.this.token));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -116,7 +115,7 @@ public class ClientLoginHandler implements IClientLoginHandler {
|
|||
this.connection.closeChannel("Unerwartetes Beweis-Paket");
|
||||
return;
|
||||
}
|
||||
if(!Arrays.equals(this.token, packet.getToken())) {
|
||||
if(!packet.verifyToken(this.server.getServerKey(), this.token)) {
|
||||
this.connection.closeChannel("Fehlerhaftes Beweis-Token");
|
||||
return;
|
||||
}
|
||||
|
@ -189,7 +188,7 @@ public class ClientLoginHandler implements IClientLoginHandler {
|
|||
return;
|
||||
}
|
||||
this.state = LoginState.AUTHENTICATING;
|
||||
this.connection.sendPacket(new LPacketResponse(packet.getToken(this.server.getKeypair().getPrivate())));
|
||||
this.connection.sendPacket(new LPacketResponse(this.server.getKeypair().getPrivate(), packet.getToken()));
|
||||
}
|
||||
|
||||
public void handleLoginSuccess(RPacketLoginSuccess packet)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue