1. ホーム
  2. java

[解決済み] Javaでパスワードから鍵を派生させる場合、なぜSecretKeySpecが必要なのですか?

2022-02-12 16:12:30

質問内容

とはどのような違いがあるのでしょうか? SecretKeySecretKeySpec のクラスは、Javaでは?

のドキュメントは SecretKeySpec は言う。

バイト配列からSecretKeyを作成するのに使用することができます。

このコードでは、もし私が secretKey.getEncoded() または secret.getEncoded() を16進数で表示すると、どちらも同じ出力になります。では、なぜ 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 には、関連するアルゴリズム名があります。このため SecretKey というアルゴリズムで "DES" を、例えばAESの鍵が必要なコンテキストで使用することができます。

あなたのコードでは、次の行で SecretKey :

SecretKey secretKey = factory.generateSecret(spec);

しかし、この時点では、キーは ではなく AESキーです。もしあなたが secretKey.getAlgorithm() の場合、その結果は "PBKDF2WithHmacSHA1" . これが実際にAESキーであることをJavaに伝える何らかの方法が必要です。

これを行う最も簡単な方法は、新しい SecretKeySpec オブジェクトを作成し、元のキーデータを使ってアルゴリズム名を明示的に指定します。

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

注:個人的には secret として SecretKey この後、具体的な実装を気にする必要はないと思いますので。