Ich habe zwei Methoden zum Verschlüsseln/Entschlüsseln von JSON-Nachrichten zwischen Clients und einem Server. Der Server verfügt über ein Paar RSA-Schlüssel (einen privaten und einen öffentlichen) und einen Client. Darüber hinaus haben beide Zugriff auf einen symmetrischen Sitzungsschlüssel, der beim ersten Herstellen einer Kommunikation generiert wird, der zum Chiffrieren der JSON-Nachricht verwendet wird, da der Kanal selbst nicht sicher ist. Der Client generiert einen AES-Schlüssel (Sitzungsschlüssel), den er dann mit dem öffentlichen Schlüssel des Servers (allen bekannt) verschlüsselt und an den Server sendet, der den Sitzungsschlüssel entschlüsselt und in einer HashMap
unter der ID des Kunden speichert.JAVA - Nicht übereinstimmende AES-Schlüssellängen
Hier ist das Problem, obwohl: Ich habe die Schlüssellänge vor dem Senden überprüft und es ist 16 Bytes lang. Wenn der Server den verschlüsselten Sitzungsschlüssel empfängt und entschlüsselt, ist er 24 Byte lang. Ich nehme an, dass zwischendurch etwas schief gelaufen ist, entweder während der Chiffre oder der Entschlüsselungsoperation. Dies ist ein Problem, da der Server die Anforderung nicht entschlüsseln und lesen kann, wenn der Client mit dem Senden von Anforderungen (in Form von verschlüsselten JSON-Nachrichten) beginnen möchte, da der Schlüssel die falsche Größe hat (java.security.InvalidKeyException
: Ungültige Schlüsselgröße) oder Standardparameter).
Die Chiffre/entziffern Methoden unten geschrieben werden:
public String cipher(Key key, String alg, String msg){
try {
Cipher c = Cipher.getInstance(alg);
c.init(Cipher.ENCRYPT_MODE, key);
return encoder.encodeToString(c.doFinal(msg.getBytes("UTF-8")));
} catch (IllegalBlockSizeException e) {
(...)
}
}
Die encoder
/decoder
von java.util.Base64
sind.
public String decipher(Key key, String alg, String msg){
try {
Cipher c = Cipher.getInstance(alg);
c.init(Cipher.DECRYPT_MODE,key);
return new String(c.doFinal(decoder.decode(msg)), "UTF-8");
} catch (IllegalBlockSizeException e) {
(...)
}
}
Client-Chiffrierung und Senden der Sitzungsschlüssel:
SecretKey sk = KeyGenerator.getInstance("AES/CBC/PKCS5Padding").generateKey();
System.out.println(sk.getEncoded().length) //length = 16 bytes
String sessionKey = cipher(client.getServerPublicKey(),
"RSA/ECB/PKCS5Padding", encoder.encodeToString(sk.getEncoded()));
printWriter.write("{(...), \"key\":\"" + sessionKey + "\"}");
Server die chiffrierten Sitzungsschlüssel zu empfangen und es in der HashMap
Sparend:
byte[] aux = decipher(registry.getServerPrivateKey(),
"RSA/ECB/PKCS5Padding", data.get("key").toString().replace("\"", ""))
.getBytes("UTF-8");
System.out.println(aux.length) //length = 24 bytes
registry.addSession(..., new SecretKeySpec(aux, 0, aux.length, "AES"));
Ich habe versucht, verschiedene Algorithmen und verschiedene Polsterungen , aber ich kann nicht herausfinden, wo der Fehler ist.
Diese sicherlich das Problem der Schlüsselgröße gelöst, es ist jetzt 16 Bytes auf Client- und Server-Seiten, danke! Dieser 'encoder.encodeToString (sk.getEncoded())' war der Überrest einer früheren Implementierung, die ich versucht hatte. –