2014-12-05 3 views
0

Я реализую WebService на Java, в котором серверу необходимо отправить ключ 3DES клиенту с использованием алгоритма RSA. Симметричный генерируется сервером. И сервер, и клиент имеют свои собственные пары ключей RSA, которые ранее были обменены.Обмен ключами 3DES с RSA в Java

В этом коде сервер отправляет симметричный ключ клиенту.

@WebMethod 
public byte[] getSymmetricKey(){ 
    try{ 
     Cipher cipher = Cipher.getInstance("RSA"); 

     // First, encrypts the symmetric key with the client's public key 
     cipher.init(Cipher.ENCRYPT_MODE, this.clientKey); 
     byte[] partialCipher = cipher.doFinal(this.key.getBytes()); 

     // Finally, encrypts the previous result with the server's private key 
     cipher.init(Cipher.ENCRYPT_MODE, this.privateKey); 
     byte[] cipherData = cipher.doFinal(partialCipher); 

     return cipherData; 
    }catch (Exception ex){ 
     ex.printStackTrace(); 
    } 

} 

При запуске шифрования с закрытым ключом сервера, я получаю ошибку IllegalBlockSizeException. Почему я получаю это исключение, если заполнение активировано по умолчанию? Я также попытался явно активировать заполнение с помощью Cipher.getInstance("RSA/ECB/PKCS1Padding"). Наконец, вот выход исключения:

SEVERE: javax.crypto.IllegalBlockSizeException: Data must not be longer than 245 bytes 
javax.crypto.IllegalBlockSizeException: Data must not be longer than 245 bytes 
    at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:346) 
    at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:391) 
    at javax.crypto.Cipher.doFinal(Cipher.java:2087) 
    at server.FileTransfererImpl.getSymmetricKey(FileTransfererImpl.java:112) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at sun.reflect.misc.Trampoline.invoke(Unknown Source) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at sun.reflect.misc.MethodUtil.invoke(Unknown Source) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at com.sun.xml.internal.ws.api.server.MethodUtil.invoke(Unknown Source) 
    at com.sun.xml.internal.ws.api.server.InstanceResolver$1.invoke(Unknown Source) 
    at com.sun.xml.internal.ws.server.InvokerTube$2.invoke(Unknown Source) 
    at com.sun.xml.internal.ws.server.sei.EndpointMethodHandler.invoke(Unknown Source) 
    at com.sun.xml.internal.ws.server.sei.SEIInvokerTube.processRequest(Unknown Source) 
    at com.sun.xml.internal.ws.api.pipe.Fiber.__doRun(Unknown Source) 
    at com.sun.xml.internal.ws.api.pipe.Fiber._doRun(Unknown Source) 
    at com.sun.xml.internal.ws.api.pipe.Fiber.doRun(Unknown Source) 
    at com.sun.xml.internal.ws.api.pipe.Fiber.runSync(Unknown Source) 
    at com.sun.xml.internal.ws.server.WSEndpointImpl$2.process(Unknown Source) 
    at com.sun.xml.internal.ws.transport.http.HttpAdapter$HttpToolkit.handle(Unknown Source) 
    at com.sun.xml.internal.ws.transport.http.HttpAdapter.handle(Unknown Source) 
    at com.sun.xml.internal.ws.transport.http.server.WSHttpHandler.handleExchange(Unknown Source) 
    at com.sun.xml.internal.ws.transport.http.server.WSHttpHandler.handle(Unknown Source) 
    at com.sun.net.httpserver.Filter$Chain.doFilter(Unknown Source) 
    at sun.net.httpserver.AuthFilter.doFilter(Unknown Source) 
    at com.sun.net.httpserver.Filter$Chain.doFilter(Unknown Source) 
    at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(Unknown Source) 
    at com.sun.net.httpserver.Filter$Chain.doFilter(Unknown Source) 
    at sun.net.httpserver.ServerImpl$Exchange.run(Unknown Source) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
    at java.lang.Thread.run(Unknown Source) 
+0

Является ли закрытый ключ длиннее 245 байт? –

+1

На какой строке происходит это исключение? Вы не должны повторно использовать экземпляры Cipher. Кроме того, вы не можете зашифровать с помощью закрытого ключа RSA. –

+0

@MartinKonecny ​​Да, это так. Дело в том, что он не показывает никаких исключений, когда я использую только закрытый ключ сервера для этой задачи. Это вызывает только исключение, когда я пытаюсь использовать два разных ключа (частный и закрытый для клиента). Частичный Cipher (данные для второго шага) не слишком велик (256 байт), но, возможно, алгоритм RSA предназначен для шифрования действительно небольших данных только? –

ответ

1

Я исследовал SOEM материала сегодня и нашел этот вопрос. Поскольку на него не ответили, я оставлю это здесь для дальнейшего использования.

Согласно PKCS # 1, алгоритм RSAES-PKCS1-V1_5-ENCRYPT может шифровать до k - 11 байт, где k - это «размер» ключа в байтах. Эти 11 байтов используются для «заголовков».

Если вы используете ключ RSA 2048 бит, который дает вам k = 256 и вы можете зашифровать до 256 - 11 = 245 байт данных.

Проверьте фактический размер this.key.

Смежные вопросы