Короче говоря, причина различия заключается в том, что алгоритм PBKDF2 в режимах # 1 и # 2 использует схему 2 PKCS # 5 v2 (PKCS5S2) для итеративной генерации ключа, но поставщик BouncyCastle для "PBEWITHHMACSHA1" в режиме # 3 используетвместо этого алгоритм PKCS # 12 v1 (PKCS12).Это совершенно разные алгоритмы генерации ключей, поэтому вы получите разные результаты.
Подробнее о том, почему это так и почему вы получаете результаты разных размеров, объясняется ниже.
Во-первых, когда вы 'При создании JCE KeySpec параметр keyLength выражает «предпочтение» провайдеру, какой размер ключа вы хотите.Начиная с API документы :
Примечание: это используется для указания предпочтения длины ключа для шифров с переменным размером ключа.Фактический размер ключа зависит от реализации каждого провайдера.
Поставщики Bouncy Castle не соблюдают этот параметр, судя по источнику JCEPBEKey , поэтому вы должны ожидатьполучить 160-битный ключ от любого провайдера BC, который использует SHA-1 при использовании JCE API.
Вы можете подтвердить это, программно обратившись к методу getKeySize()
в возвращенной переменной keybc
в вашем тестекод:
Key keybc = factorybc.generateSecret(keyspecbc);
// ...
Method getKeySize = JCEPBEKey.class.getDeclaredMethod("getKeySize");
getKeySize.setAccessible(true);
System.out.println(getKeySize.invoke(keybc)); // prints '160'
Теперь, чтобы понять, что соответствует провайдеру PBEWITHHMACSHA1, вы можете найти в исходном коде BouncyCastleProvider :
put("SecretKeyFactory.PBEWITHHMACSHA1",
"org.bouncycastle.jce.provider.JCESecretKeyFactory$PBEWithSHA");
И реализация JCESecretKeyFactory.PBEWithSHA выглядит следующим образом:
public static class PBEWithSHA
extends PBEKeyFactory
{
public PBEWithSHA()
{
super("PBEwithHmacSHA", null, false, PKCS12, SHA1, 160, 0);
}
}
Вы могли видеть выше, что эта фабрика ключей использует алгоритм PKCS # 12 v1 ( PKCS12 )для итеративной генерации ключей.Но алгоритм PBKDF2, который вы хотите использовать для хеширования паролей, использует PKCS # 5 v2, схема 2 ( PKCS5S2 ).Вот почему вы получаете разные результаты.
Я быстро просмотрел поставщиков JCE, зарегистрированных в BouncyCastleProvider
, но не смог увидеть каких-либо алгоритмов генерации ключей, которые использовали PKCS5S2 ввсе, не говоря уже о том, который также использует его с HMAC-SHA-1.
Так что я думаю, что вы застряли либо с использованием реализации Sun (режим № 1 выше) и потерей переносимости на других JVM, либо с помощьюклассы Bouncy Castle (режим № 2 выше) и требуют библиотеки BC во время выполнения.
В любом случае, вам, вероятно, следует переключиться на 160-битные ключи, чтобы не урезать сгенерированный хэш SHA-1.т.к.