【发布时间】:2018-01-18 13:30:04
【问题描述】:
根据我的研究,我了解到这是使用 RSA 封装 AES 会话密钥的正确方法:
import java.security.*;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
public class Main {
public static void main(String args[]) throws Exception {
KeyGenerator aesKeyGen = KeyGenerator.getInstance("AES");
aesKeyGen.init(256);
SecretKey secretKey = aesKeyGen.generateKey();
Base64.Encoder encoder = Base64.getEncoder().withoutPadding();
Cipher cipher = Cipher.getInstance("RSA");
KeyPairGenerator rsaKeyGen = KeyPairGenerator.getInstance("RSA");
rsaKeyGen.initialize(4096);
KeyPair keyPair = rsaKeyGen.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
cipher.init(Cipher.WRAP_MODE, publicKey);
byte[] wrappedKey = cipher.wrap(secretKey);
cipher.init(Cipher.UNWRAP_MODE, privateKey);
SecretKey unwrappedKey = (SecretKey)cipher.unwrap(wrappedKey, "AES", Cipher.SECRET_KEY);
System.out.println(encoder.encodeToString(wrappedKey));
System.out.println(encoder.encodeToString(secretKey.getEncoded()));
System.out.println(encoder.encodeToString(unwrappedKey.getEncoded()));
}
}
我的问题是:
- 我应该继续使用
Cipher.getInstance("RSA"),改用Cipher.getInstance("RSA/ECB/PKCS1Padding")还是其他方式? - 除了使用 EC 之外,我怎样才能做与上面相同的事情?
- 密钥封装和密钥封装一样吗?
- 我是否需要像处理数组一样(例如
Arrays.fill(array, (byte)0))或调用getEncoded()一样清除secretKey使用的内存?
为了回答我的第二个问题,我发现我应该使用:
KeyPairGenerator ecKeyGen = KeyPairGenerator.getInstance("EC");
但是我不确定在这里使用什么来代替<name>:
Cipher cipher = Cipher.getInstance("<name>");
我还发现我可以通过这样做来选择要使用的曲线:
...
ECGenParameterSpec ecsp = new ECGenParameterSpec("sect571k1");
ecKeyGen.initialize(571);
...
但是,我不知道我应该在这里使用什么参数来代替<name>:
new ECGenParameterSpec("<name>");
我认为一些不错的候选人如下:
secp521r1, nistp521, sect571r1, nistb571, nistb571, sect571k1, nistk571 nistk571, sect163r2
还有其他选择吗?你能帮我选一个最好的吗?实例化一个ECGenParameterSpec对象来设置EC的初始化参数KeyPairGenerator够了吗?
【问题讨论】:
标签: java cryptography rsa public-key-encryption elliptic-curve