简体   繁体   English

在 Java 中使用 RSA 加密 SecretKey

[英]Encrypt a SecretKey with RSA in Java

I'm working on a client-server secure protocol where I need to use RSA in Java to encrypt a SecretKey for HMAC digests because the key has to be sent to the server.我正在研究客户端-服务器安全协议,我需要在 Java 中使用 RSA 来加密 HMAC 摘要的 SecretKey,因为必须将密钥发送到服务器。 The encryption has two stages;加密有两个阶段; first, I need to encrypt the symmetric key with a public asymmetric key, then, that encrypted message is encrypted with a private asymmetric key.首先,我需要使用公共非对称密钥加密对称密钥,然后,使用非对称私有密钥加密该加密消息。

For this purpose I generate the SecretKey as:为此,我将 SecretKey 生成为:

public SecretKey generate(){
KeyGenerator generator = KeyGenerator.getInstance("HMACSHA256");
k = generator.generateKey();
return k;
}

Later, I use this code to encrypt any byte array with a public key:后来,我使用此代码用公钥加密任何字节数组:

public byte[] encryptPublic(PublicKey key, byte[] array){
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encrypted = cipher.doFinal(array);
return encrypted;
}

The code for encryption with a private key is the same but using a private key.使用私钥加密的代码相同,但使用私钥。

For the RSA encryption I'm using 1024 bit long asymmetric keys so I have two main questions:对于 RSA 加密,我使用的是 1024 位长的非对称密钥,所以我有两个主要问题:

  1. How can I turn my SecretKey to a byte array in order to encrypt it with RSA and a public key?如何将我的 SecretKey 转换为字节数组,以便使用 RSA 和公钥对其进行加密?
  2. As the public key encryption produces a byte array with 128 bytes, how can I encrypt that message again with a private key if the key is 1024 bits long and can only encrypt a 117 byte long message?由于公钥加密产生一个 128 字节的字节数组,如果密钥是 1024 位长并且只能加密 117 字节长的消息,我如何使用私钥再次加密该消息?
  1. How can I turn my SecretKey to a byte array in order to encrypt it with RSA and a public key?如何将我的 SecretKey 转换为字节数组,以便使用 RSA 和公钥对其进行加密?

That's called wrapping:这就是所谓的包装:

public static byte[] wrapKey(PublicKey pubKey, SecretKey symKey)
        throws InvalidKeyException, IllegalBlockSizeException {
    try {
        final Cipher cipher = Cipher
                .getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding");
        cipher.init(Cipher.WRAP_MODE, pubKey);
        final byte[] wrapped = cipher.wrap(symKey);
        return wrapped;
    } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
        throw new IllegalStateException(
                "Java runtime does not support RSA/ECB/OAEPWithSHA1AndMGF1Padding",
                e);
    }
}

Note that this explicitly doesn't convert to byte[] first.请注意,这不会首先转换为byte[] That's because the key might well be within eg a hardware security module.那是因为密钥很可能位于例如硬件安全模块中。 In a HSM the wrapping may be possible, but the conversion to byte[] in local memory would usually not be possible.在 HSM 中,包装可能是可能的,但在本地内存中转换为byte[]通常是不可能的。


  1. As the public key encryption produces a byte array with 128 bytes, how can I encrypt that message again with a private key if the key is 1024 bits long and can only encrypt a 117 byte long message?由于公钥加密产生一个 128 字节的字节数组,如果密钥是 1024 位长并且只能加密 117 字节长的消息,我如何使用私钥再次加密该消息?

You shouldn't do this and you cannot do this either.你不应该这样做,你也不能这样做。 The reason that you shouldn't do it because encryption with the private key does not provide confidentiality , as anybody would have access to the public key.您不应该这样做的原因是因为使用私钥加密不提供机密性,因为任何人都可以访问公钥。

Padding is required to perform secure RSA encryption.执行安全 RSA 加密需要填充。 The padding overhead (of 11 bytes for PKCS#1 v1.5 style padding) is there prohibiting you to encrypt with the private key.填充开销(PKCS#1 v1.5 样式填充的 11 字节)禁止您使用私钥进行加密。

Note that the entire operation: encryption with a private key isn't even specified in PKCS#1 - it's not a legit operation.请注意,整个操作:使用私钥加密甚至没有在 PKCS#1 中指定 - 这不是合法操作。


Usually the much more secure ephemeral-ephemeral (EC)DH is used to establish keys in transport protocols, using the private key(s) only for authentication.通常更安全的 ephemeral-ephemeral (EC)DH 用于在传输协议中建立密钥,仅将私钥用于身份验证。 You may want to take a hint from the (draft versions of) TLS 1.3.您可能想从 TLS 1.3(的草案版本)中获得一些提示。 Or you may just want to use TLS or the handshake portion of it.或者您可能只想使用 TLS 或其握手部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM