2014-11-21 4790 views
7

Java中的SecretKeySecretKeySpec类有什么区别?为什么从Java中的密码派生密钥时需要SecretKeySpec?

SecretKeySpec文档说:

它可以用来从一个字节数组

构造生成SecretKey在该代码中,如果我打印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

回答

10

每个SecretKey都有一个相关的算法名称。例如,在需要AES密钥的上下文中,不能使用SecretKey和算法"DES"

在代码中,下面这行产生SecretKey

SecretKey secretKey = factory.generateSecret(spec); 

然而,在这一点上,关键是 AES密钥。如果您致电secretKey.getAlgorithm(),则结果为"PBKDF2WithHmacSHA1"。您需要某种方式告诉Java,这实际上是一个AES密钥。

做到这一点,最简单的方法是建立一个新的SecretKeySpec对象,使用原始的关键数据,并明确指定算法名称:

SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(),"AES"); 

注:我会亲自宣布secret作为SecretKey,因为我不要以为在这之后你需要关心具体的实施。

+0

实现“每SecretKey的具有相关联的算法的名称。” ,这不会使加密不太安全吗?不应该密钥应该是独立的算法?例如,如果某人获得了密钥,他们是不是可以识别用于加密的算法? – 2014-11-21 13:13:54

+8

强大的密码学基于每个人都知道的一切,*除了*密钥的价值。一旦有人拥有了你的密钥,搞清楚你如何加密数据是一项微不足道的任务。所以不,你的算法不需要保密。 – 2014-11-21 14:15:40

7

SecretKey的仅仅是需要特定的提供者的实现的接口。 SecretKeySpec是一个具体的类,允许从现有的密钥材料中轻松构建SecretKey。因此,要获得SecretKey,您需要使用适当的工厂类或SecretKeySpec作为快捷方式。

3

SecretKey是一个接口,SecretKeySpecSecretKey

相关问题