[英]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 位长的非对称密钥,所以我有两个主要问题:
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[]
通常是不可能的。
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.