为什么在 Java 中从密码派生密钥时需要 SecretKeySpec?

2022-09-03 04:06:09

Java中的类与类有什么区别?SecretKeySecretKeySpec

的文档说: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


答案 1

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

在代码中,以下行生成:SecretKey

SecretKey secretKey = factory.generateSecret(spec);

但是,此时密钥不是 AES 密钥。如果要调用 ,则结果为 。你需要一些方法来告诉Java这实际上是一个AES密钥。secretKey.getAlgorithm()"PBKDF2WithHmacSHA1"

执行此操作的最简单方法是构造一个新对象,使用原始键数据并显式指定算法名称:SecretKeySpec

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

注意:我个人会声明为,因为我认为您不需要关心在此之后的具体实现。secretSecretKey


答案 2

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


推荐