[英]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.