在Java中使用RSA加密加密密钥
我正在开发一个客户机-服务器安全协议,在该协议中,我需要使用Java中的RSA对HMAC摘要的SecretKey进行加密,因为密钥必须发送到服务器。加密分为两个阶段;首先,我需要用公共非对称密钥加密对称密钥,然后,用私有非对称密钥加密加密的消息 为此,我将生成SecretKey,如下所示:在Java中使用RSA加密加密密钥,java,encryption,rsa,encryption-asymmetric,secret-key,Java,Encryption,Rsa,Encryption Asymmetric,Secret Key,我正在开发一个客户机-服务器安全协议,在该协议中,我需要使用Java中的RSA对HMAC摘要的SecretKey进行加密,因为密钥必须发送到服务器。加密分为两个阶段;首先,我需要用公共非对称密钥加密对称密钥,然后,用私有非对称密钥加密加密的消息 为此,我将生成SecretKey,如下所示: public SecretKey generate(){ KeyGenerator generator = KeyGenerator.getInstance("HMACSHA256"); k = genera
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);
}
}
请注意,这不会首先显式转换为字节[]
。这是因为密钥很可能位于硬件安全模块内。在HSM中,包装是可能的,但是在本地内存中转换为字节[]
通常是不可能的
通常,更安全的临时(EC)DH用于在传输协议中建立密钥,仅将私钥用于身份验证。您可能希望从TLS1.3(草案版本)中得到提示。或者您可能只想使用TLS或其中的握手部分。一些评论。1) 在任何地方都不要在加密中使用默认值。在
getInstance()
方法中,始终指定由三部分组成的完整转换字符串。2). 不要使用私钥加密,而是执行签名。您可以使用Signature
类来实现这一点。3) 键(包括SecretKeys)使用getEncoded()
方法返回以某种标准格式表示键的字节数组。对于对称密钥,即SecretKey
实例,由getEncoded()
返回的字节数组只是原始密钥字节。对于Q2:您可以使用随机AES密钥加密密文,然后使用另一轮RSA加密新的AES密钥,但为什么要这样做?