2014-12-05 51 views
0

我正在实现一个Java服务器中的WebService,其中服务器需要使用RSA算法向客户端发送3DES密钥。对称由服务器生成。服务器和客户端都有自己的RSA密钥对,之前已经交换过。3DES与Java中的RSA密钥交换

在此代码中,服务器将对称密钥发送到客户端。

@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字节? – 2014-12-05 18:21:09

+1

这个异常发生在哪一行?您不应该重复使用'Cipher'实例。另外,您不能使用RSA私钥进行加密。 – 2014-12-05 18:22:14

+0

@MartinKonecny是的。问题是,当我仅使用服务器的私钥执行此任务时,它不会显示异常。当我尝试使用两个不同的密钥(服务器的私有和客户端公共)时,它只会引发异常。 partialCipher(第二步的数据)不是太大(256字节),但是RSA算法可能只是为了加密真正的小数据? – 2014-12-05 18:28:55

回答

1

我今天研究SOEM的东西,发现了这个问题。由于没有得到答复,我将留在这里供将来参考。

根据PKCS#1,RSAES-PKCS1-V1_5-ENCRYPT算法可以加密多达k - 11字节,其中k是密钥的“大小”(以字节为单位)。这11个字节用于“标题”。

如果您使用的是2048位的RSA密钥,则会给您k = 256,并且您可以加密至多256 - 11 = 245字节的数据。

检查this.key的实际尺寸。