簡體   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