JavaのSecretKey
クラスとSecretKeySpec
クラスの違いは何ですか?
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
には、関連付けられたアルゴリズム名があります。たとえば、AESキーが必要なコンテキストでは、アルゴリズム_"DES"
_でSecretKey
を使用できません。
コードでは、次の行によってSecretKey
が生成されます。
_SecretKey secretKey = factory.generateSecret(spec);
_
ただし、この時点でのキーはnot AESキーです。 secretKey.getAlgorithm()
を呼び出すと、結果は_"PBKDF2WithHmacSHA1"
_になります。 Java=これが実際にはAESキーであることを伝える何らかの方法が必要です。
これを行う最も簡単な方法は、元のキーデータを使用し、アルゴリズム名を明示的に指定して、新しいSecretKeySpec
オブジェクトを作成することです。
_SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(),"AES");
_
注:secret
はSecretKey
として個人的に宣言します。これは、この後の具体的な実装について気にする必要がないためです。
SecretKeyは、プロバイダー固有の実装を必要とする単なるインターフェースです。 SecretKeySpecは、既存の鍵素材からSecretKeyを簡単に構築できる具象クラスです。したがって、SecretKeyを取得するには、適切なファクトリクラスまたはSecretKeySpecをショートカットとして使用する必要があります。
SecretKey
はインターフェースであり、SecretKeySpec
はSecretKey
の実装です