繁体   English   中英

在 Java 中使用 RSA 加密 SecretKey

[英]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 位长的非对称密钥,所以我有两个主要问题:

  1. 如何将我的 SecretKey 转换为字节数组,以便使用 RSA 和公钥对其进行加密?
  2. 由于公钥加密产生一个 128 字节的字节数组,如果密钥是 1024 位长并且只能加密 117 字节长的消息,我如何使用私钥再次加密该消息?
  1. 如何将我的 SecretKey 转换为字节数组,以便使用 RSA 和公钥对其进行加密?

这就是所谓的包装:

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[]通常是不可能的。


  1. 由于公钥加密产生一个 128 字节的字节数组,如果密钥是 1024 位长并且只能加密 117 字节长的消息,我如何使用私钥再次加密该消息?

你不应该这样做,你也不能这样做。 您不应该这样做的原因是因为使用私钥加密不提供机密性,因为任何人都可以访问公钥。

执行安全 RSA 加密需要填充。 填充开销(PKCS#1 v1.5 样式填充的 11 字节)禁止您使用私钥进行加密。

请注意,整个操作:使用私钥加密甚至没有在 PKCS#1 中指定 - 这不是合法操作。


通常更安全的 ephemeral-ephemeral (EC)DH 用于在传输协议中建立密钥,仅将私钥用于身份验证。 您可能想从 TLS 1.3(的草案版本)中获得一些提示。 或者您可能只想使用 TLS 或其握手部分。

暂无
暂无

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

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