[英]Encrypt a SecretKey with RSA in Java
我正在研究客户端-服务器安全协议,我需要在 Java 中使用 RSA 来加密 HMAC 摘要的 SecretKey,因为必须将密钥发送到服务器。 加密有两个阶段; 首先,我需要使用公共非对称密钥加密对称密钥,然后,使用非对称私有密钥加密该加密消息。
为此,我将 SecretKey 生成为:
public SecretKey generate(){
KeyGenerator generator = KeyGenerator.getInstance("HMACSHA256");
k = generator.generateKey();
return k;
}
后来,我使用此代码用公钥加密任何字节数组:
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;
}
使用私钥加密的代码相同,但使用私钥。
对于 RSA 加密,我使用的是 1024 位长的非对称密钥,所以我有两个主要问题:
这就是所谓的包装:
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);
}
}
请注意,这不会首先转换为byte[]
。 那是因为密钥很可能位于例如硬件安全模块中。 在 HSM 中,包装可能是可能的,但在本地内存中转换为byte[]
通常是不可能的。
你不应该这样做,你也不能这样做。 您不应该这样做的原因是因为使用私钥加密不提供机密性,因为任何人都可以访问公钥。
执行安全 RSA 加密需要填充。 填充开销(PKCS#1 v1.5 样式填充的 11 字节)禁止您使用私钥进行加密。
请注意,整个操作:使用私钥加密甚至没有在 PKCS#1 中指定 - 这不是合法操作。
通常更安全的 ephemeral-ephemeral (EC)DH 用于在传输协议中建立密钥,仅将私钥用于身份验证。 您可能想从 TLS 1.3(的草案版本)中获得一些提示。 或者您可能只想使用 TLS 或其握手部分。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.