Симметричное шифрование Java, передавая nonce
В настоящее время у меня есть один метод, который работает на моей стороне сервера, который возвращает случайно сгенерированную строку, которая выглядит следующим образом;
public String returnString(){
String randString = nextSessionId();
return randString;
}
На стороне КЛИЕНТА у меня есть метод, который запрашивает randomString у СЕРВЕРА, шифрует его с помощью ключа клиента, запечатывает его в SealedObject и затем отвечает SealedObject, это выглядит так;
public boolean validateClient(String loggedInKey) throws Exception{
/* Testing */
String randString = this.aI.returnString(); // Client requests a string/ server returns
System.out.println("This is what the server gave me: "+randString);
String encryptionKey = loggedInKey;
SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES");
Cipher ecipher = Cipher.getInstance("AES");
ecipher.init(Cipher.ENCRYPT_MODE, key);
SealedObject sealedClientReply = new SealedObject(randString, ecipher); // Client encrypts returned string seals it
System.out.println("This is what I'm sending back: "+sealedClientReply);
if(this.aI.clientValidate(sealedClientReply, loggedInKey)){
System.out.println("Client validated!");
return true;
}else{
return false;
}
}
Затем у меня на СЕРВЕРЕ есть метод, который берет этот SealedObject, распечатывает его и использует ключ Клиента, которым он делится с ним, для дешифрования SealedObject, и, надеюсь, выдает тот же ключ, который Сервер отправил клиенту, он выглядит следующим образом;
public boolean clientValidate(SealedObject sealedClientReply, String loggedInKey) throws Exception{
String encryptionKey = loggedInKey;
SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES");
Cipher dcipher = Cipher.getInstance("AES");
dcipher.init(Cipher.DECRYPT_MODE, key);
sealedClientReply.getObject(dcipher); // Server decrypts object
System.out.println("I received this from the client: "+sealedClientReply);
String decryptedClientReply= (String) sealedClientReply.getObject(dcipher);
System.out.println("This is what I received decrypted: "+decryptedClientReply);
//if(decryptedClientReply.equals(randString)){
// return true;
//}else{
// return false;
//}
return true;
}
На мой взгляд, этот подход работал отлично и был очень безопасным. Однако у меня сейчас есть один серьезный недостаток. Как вы можете видеть из закомментированного кода в последнем методе, decryptedClientReply не может быть равен randString, потому что метод, который выполняет это сравнение, на самом деле не знает, какой randString сервер отправил клиенту в первую очередь.
Если я передам randString в этот метод, это все еще безопасно? Если это не безопасно, есть ли другой способ, которым я мог бы осуществить этот симметричный подход?