2017-02-22 46 views
-1

EDIT: Второй вопрос больше не нужен. Проблема возникла из-за проблем с заполнением; изменив параметры шифра на «RSA/ECB/PKCS1Padding», который был уже реализован в других используемых шифрах.Как мне зашифровать и отправить ключ DES с закрытым ключом RSA, а затем открытым ключом на Java?

Для школьного задания мне нужно создать две программы на Java (клиент и сервер), которые используют асимметричное шифрование RSA для создания и согласования ключа сеанса, использующего шифрование DES. Окончательное сообщение в обмене содержит ключ, который был сгенерирован клиентом, который зашифрован частным ключом клиента, а затем снова зашифрован с использованием открытого ключа сервера. Затем сервер может расшифровать сообщение, используя его закрытый ключ, а затем снова расшифровать его с помощью открытого ключа клиента для получения ключа DES. Однако первое шифрование приводит к массиву байтов размером 256, а для второго шифрования требуется массив байтов, который меньше этого. Есть ли способ манипулировать данными, чтобы я мог дважды зашифровать ключ, как указано в задании? Обратите внимание, что это требование, как и алгоритм DES для ключа сеанса.

Кроме того, не считая второго шифрования, так что следующая часть назначения, которая позволяет клиенту и серверу отправлять зашифрованные сообщения друг другу, создает другую проблему. В настоящее время клиент обертывает ключ с помощью открытого ключа сервера, а затем сервер разворачивает его с помощью своего закрытого ключа. Однако развертывание ключа сеанса на стороне сервера вызывает InvalidKeyException; длина развернутой клавиши составляет 256 байтов, что совершенно неверно.

На стороне сервера, у меня есть:

 byte[] m4 = new byte[256]; 
     datIn.read(m4); 
     cUwp.init(Cipher.UNWRAP_MODE, myKey); 
     ks = (SecretKey)cUwp.unwrap(m4, "DES", Cipher.SECRET_KEY); 
     System.out.println("Recieved key:\n" + ks); 
     try{ 
      Cipher desCipher = Cipher.getInstance("DES"); 
      desCipher.init(Cipher.DECRYPT_MODE, ks); 
     } 
     catch(NoSuchPaddingException|InvalidKeyException e){ 
      System.out.println("Error: " + e); 
     } 

На стороне клиента:

 KeyGenerator keygen = KeyGenerator.getInstance("DES"); 
     SecretKey key = keygen.generateKey(); 
     cWrp.init(Cipher.WRAP_MODE, theirKey); 
     byte[] m4 = cWrp.wrap(key); 
     datOut.write(m4); 
     ks = key; 
     try{ 
      Cipher desCipher = Cipher.getInstance("DES"); 
      desCipher.init(Cipher.DECRYPT_MODE, ks); 
     } 
     catch(NoSuchPaddingException|InvalidKeyException e){ 
      System.out.println("Error: " + e); 
     } 

Я не получаю никаких расхождений размера в любой другой части моего кода; любые другие расшифрованные сообщения являются надлежащим размером, но ни один из них не использует метод wrap(), поскольку они являются строками, а не SecretKeys. Есть что-то, что мне не хватает?

+1

Я не знаю, кто это учит, но DES небезопасен, PKCS # 1 небезопасен (когда применяются атаки дополнений, например, во время транспортной безопасности), а шифрование с закрытым ключом - хотя похожее - не является генерацией подписи. –

ответ

4

Вы делаете это совершенно неправильно. Шифрование должно выполняться с помощью общедоступного ключа и дешифрования с помощью закрытого ключа. В противном случае любой может его расшифровать.

Бросьте все это и используйте TLS.

+0

Вы неправильно поняли. В задании явно указано, что нужно дважды зашифровать сообщение, один раз с помощью закрытого ключа отправителя, а затем с открытым ключом получателя, а затем расшифровать его с помощью закрытого ключа получателя, а затем открытого ключа отправителя. Первое шифрование действует как подпись, а второе шифрование обеспечивает безопасность. Кроме того, TLS не является опцией в соответствии со спецификациями назначения. – Sean

+3

Ответ правильный. Вы упомянули, что вы шифруете с помощью закрытого ключа клиента, а затем расшифровываете его с помощью открытого ключа клиента. Это не то, как работает RSA. Это не обеспечивает никакой безопасности. Может быть, вы хотите подписать его с помощью закрытого ключа клиента, а затем проверить подпись с помощью открытого ключа? – jackgu1988