Java中的SecretKey
和SecretKeySpec
类之间有什么区别?SecretKeySpec
的文档说:
在此代码中,如果我以十六进制打印secretKey.getEncoded()
或secret.getEncoded()
,则两者都给出相同的输出。那么为什么我们需要SecretKeySpec
?
final String password = "test";
int pswdIterations = 65536 ;
int keySize = 256;
byte[] ivBytes;
byte[] saltBytes = {0,1,2,3,4,5,6};
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec spec = new PBEKeySpec(
password.toCharArray(),
saltBytes,
pswdIterations,
keySize
);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(),"AES");
这是
getEncoded()
的两个调用的输出:00367171843C185C043DDFB90AA97677F11D02B629DEAFC04F935419D832E697
最佳答案
每个SecretKey
都有一个关联的算法名称。例如,在需要AES key 的上下文中,不能将SecretKey
与算法"DES"
一起使用。
在您的代码中,以下行生成一个SecretKey
:
SecretKey secretKey = factory.generateSecret(spec);
但是,此时 key 不是AES key 。如果要调用
secretKey.getAlgorithm()
,则结果为"PBKDF2WithHmacSHA1"
。您需要某种方式告诉Java这实际上是一个AES key 。最简单的方法是使用原始 key 数据并显式指定算法名称来构造一个新的
SecretKeySpec
对象:SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(),"AES");
注意:我个人将
secret
声明为SecretKey
,因为我认为在此之后您不需要关心具体的实现。