Java中与RSA的3DES密钥交换

Java中与RSA的3DES密钥交换,java,cryptography,rsa,symmetric-key,Java,Cryptography,Rsa,Symmetric Key,我正在用Java实现一个WebService,其中服务器需要使用RSA算法向客户端发送一个3DES密钥。对称数据由服务器生成。服务器和客户机都有自己的RSA密钥对,这是以前交换的 在这段代码中,服务器向客户端发送对称密钥 @WebMethod public byte[] getSymmetricKey(){ try{ Cipher cipher = Cipher.getInstance("RSA"); // First, encrypts the sym

我正在用Java实现一个WebService,其中服务器需要使用RSA算法向客户端发送一个3DES密钥。对称数据由服务器生成。服务器和客户机都有自己的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)

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

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

如果您使用的是2048位RSA密钥,它将为您提供
k=256
,您最多可以加密
256-11=245
字节的数据


检查此密钥的实际大小。私钥是否超过245字节?在哪一行发生此异常?您不应该重复使用
密码
实例。此外,您不能使用RSA私钥进行加密。@MartinKonecny是的,它是。问题是,当我只使用服务器的私钥执行此任务时,它不会显示任何异常。只有当我尝试使用两个不同的密钥(服务器的私有密钥和客户端的公共密钥)时,它才会引发异常。partialCipher(第二步的数据)不是太大(256字节),但RSA算法可能只用于加密非常小的数据?@ArtjomB。嗯,我不知道。奇怪的是,我只能用服务器的私钥加密。也许我应该实现一个合适的密钥交换协议,并在双方(服务器和客户端)生成不同的3DES密钥?谢谢你。PS你为什么用3DES?已经是2014年底了。