Я пытаюсь отправить открытый ключ через сокетное соединение в Java.Хотя я очень хорошо понимаю, что Java предоставляет функции SSL для этого вида деятельности, это уникальное задание;Я не могу использовать реализацию Java.
Сервер кодирует свой открытый ключ и передает его клиенту через сокетное соединение.Когда клиент получает ключ и декодирует его, он выглядит иначе.Кроме того, данные, полученные клиентом, отличаются от данных, передаваемых сервером.Я считаю, что это вызывает у меня проблемы при попытке зашифровать имя пользователя и пароль с помощью этого ключа.
Проблема может быть воспроизведена с помощью следующего кода:
Клиент:
public class TestClient {
/**
* @param args
*/
public static void main(String[] args) {
final int sPort = 4321;
Socket sock = null;
Key serverPubKey = null;
BufferedReader clientIn = null;
// Initialise server connection
try{
sock = new Socket(InetAddress.getLocalHost(), sPort);
clientIn = new BufferedReader(new InputStreamReader(sock.getInputStream()));
} catch (UnknownHostException e) {
System.out.println("Unknown host.");
System.exit(1);
} catch (IOException e) {
System.out.println("No I/O");
System.exit(1);
}
// Get server pub key
try{
int len = Integer.parseInt(clientIn.readLine());
byte[] servPubKeyBytes = new byte[len];
sock.getInputStream().read(servPubKeyBytes,0,len);
System.out.println(servPubKeyBytes);
X509EncodedKeySpec ks = new X509EncodedKeySpec(servPubKeyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
serverPubKey = kf.generatePublic(ks);
System.out.println(serverPubKey.getEncoded());
} catch (IOException e) {
System.out.println("Error obtaining server public key 1.");
System.exit(0);
} catch (NoSuchAlgorithmException e) {
System.out.println("Error obtaining server public key 2.");
System.exit(0);
} catch (InvalidKeySpecException e) {
System.out.println("Error obtaining server public key 3.");
System.exit(0);
}
}
}
Сервер:
public class TestServer {
public static void main(String[] args) {
final int servPort = 4321;
final int RSAKeySize = 1024;
final String newline = "\n";
Key pubKey = null;
ServerSocket cServer = null;
Socket cClient = null;
PrintWriter cOut = null;
// Initialise RSA
try{
KeyPairGenerator RSAKeyGen = KeyPairGenerator.getInstance("RSA");
RSAKeyGen.initialize(RSAKeySize);
KeyPair pair = RSAKeyGen.generateKeyPair();
pubKey = pair.getPublic();
} catch (GeneralSecurityException e) {
System.out.println(e.getLocalizedMessage() + newline);
System.out.println("Error initialising encryption. Exiting.\n");
System.exit(0);
}
// Initialise socket connection
try{
cServer = new ServerSocket(servPort);
cClient = cServer.accept();
cOut = new PrintWriter(cClient.getOutputStream(), true);
} catch (IOException e) {
System.out.println("Error initialising I/O.\n");
System.exit(0);
}
// Send public key
try {
cOut.println(pubKey.getEncoded().length);
System.out.println(pubKey.getEncoded());
cClient.getOutputStream().write(pubKey.getEncoded());
cClient.getOutputStream().flush();
} catch (IOException e) {
System.out.println("I/O Error");
System.exit(0);
}
}
}
Это может быть так же просто, как сообщить мне, что мой ключ не закодирован в X509, однако похоже, что ключ восстанавливается из файла (также читается как байты) поэтому я не могу понять, почему это не сработает?
Большое спасибо заранее за любую помощь / предложения.
Редактировать: проблема решена, см. ответ Джеффри.Модифицированный (рабочий) код опубликован как ответ.