java - Java 中 3DES 与 RSA 的 key 交换

标签 java cryptography rsa symmetric-key

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

在此代码中,服务器将对称 key 发送给客户端。

@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)

最佳答案

我今天正在研究一些东西,发现了这个问题。由于尚未得到答复,我将其留在这里以供将来引用。

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

如果您使用 2048 位 RSA key ,则为 k = 256您最多可以加密 256 - 11 = 245数据字节。

检查this.key的实际大小.

关于java - Java 中 3DES 与 RSA 的 key 交换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27322235/

相关文章:

java - 具有 FreeMarker 2.3.23 依赖项的 Maven 项目无法编译

cryptography - 使用 CommonCrypto for iOS 运行 ECDH

java - PBKDF2 - 无法使用 Node 和 Java 生成相同的 Base64 编码 key

azure - 如何生成 RSAPublicKey 以馈入 JJWT RSA token 验证

ruby - Ruby 中的公钥加密演示

java - 如何在 JHipster 中调试 'Your request cannot be processed'?

java - 如何使用 java 8 的 forEach 内部的方法引用来测试谓词

Java 在使用 .equals() 返回时跳过空对象

c# - AES 在 .NET 中加密并使用 Node.js 加密解密?

java - 安卓 BigInteger ArithmeticException