ОБНОВЛЕНО 2019: Bouncycastle теперь поддерживает PBKDF2-HMAC-SHA256, начиная с
Надежная реализация PBKDF2-HMAC-SHA256 для JAVA
comment
stackoverflow.com/questions/9147463 /
- person Konstantin V. Salikhov   schedule 22.03.2014
comment
@ KonstantinV.Salikhov Я уже читал, но сложно поверить, что это полностью доказано. И если я использую это, мне нужно реализовать код для Jasypt API.
- person dgregory   schedule 22.03.2014
comment
Для будущих читателей: см. mkyong.com/java/java-aes-encryption-and -расшифровка
- person granadaCoder   schedule 01.12.2020
Ответы (3)
Прямое использование классов BouncyCastle:
PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(new SHA256Digest());
gen.init("password".getBytes("UTF-8"), "salt".getBytes(), 4096);
byte[] dk = ((KeyParameter) gen.generateDerivedParameters(256)).getKey();
person
Pasi
schedule
24.03.2014
Он доступен в Java 8:
public static byte[] getEncryptedPassword(
String password,
byte[] salt,
int iterations,
int derivedKeyLength
) throws NoSuchAlgorithmException, InvalidKeySpecException {
KeySpec spec = new PBEKeySpec(
password.toCharArray(),
salt,
iterations,
derivedKeyLength * 8
);
SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
return f.generateSecret(spec).getEncoded();
}
person
mjrduran
schedule
13.01.2015
Странно, мне не удалось заставить версию Java 8 корректно работать. Он генерировал выходные данные, но отличался от Bouncy Castle и эквивалента Node.js.
- person Kirby; 21.01.2015
@Kirby Убедитесь, что вы используете только ASCII, Java 8 немного странный в том смысле, что он использует только младшие 8 бит
char
(т.е. кодировку символов, совместимую с Windows-1252).
- person Maarten Bodewes; 15.09.2015
Работает как шарм. Кстати, если вы хотите использовать 512-байтовый дайджест, просто измените PBKDF2WithHmacSHA256 на PBKDF2WithHmacSHA512.
- person Yev Kanivets; 28.12.2018
@MaartenBodewes Он использует
UTF8.encode
для преобразования char[]
в ByteBuffer
. Т.е. все, что выходит за рамки 7-битного ASCII, будет генерировать многобайтовые последовательности, что даст вам неожиданные результаты, если вы сравните с байтовой последовательностью UTF-16, но это потому, что кодировка неожиданная, а не потому, что Java что-то игнорирует.
- person toolforger; 09.09.2020
@toolforger Из
PBEKeySpec
(Java 14): Различные механизмы PBE могут использовать разные биты каждого символа пароля. Например, механизм PBE, определенный в PKCS # 5, смотрит только на 8 младших битов каждого символа, тогда как PKCS # 12 смотрит на все 16 бит каждого символа. А PBKDF2 указан в PKCS # 5. Так что, если используется UTF-8, документация не в порядке. Можете ли вы показать, где вы нашли эту функцию кодирования?
- person Maarten Bodewes; 09.09.2020
@MaartenBodewes хм ... больше не могу найти этот код. Может, я случайно набрал код Bouncycastle. В любом случае, PBEKeySpec Javadoc, безусловно, достаточно авторитетен. Тем не менее, я не думаю, что советовать придерживаться ASCII - хорошая идея, это слишком ограничительно для многих ситуаций; людям лучше по возможности кодировать строки в кодировке UTF8. (Кроме того, форматы PKCS не обязательно являются тем, для чего вы используете механизмы PBE, возможно, Javadoc просто предупреждал, что ввод или вывод могут быть не такими, как вы думаете? Не уверен, не хватает времени на проверку, извините.)
- person toolforger; 10.09.2020
PKCS # 5 - это стандарт шифрования на основе пароля. Я не уверен, что вы имеете в виду под форматами PKCS. Старые стандарты PKCS, разработанные лабораториями RSA, охватывают большую криптографическую экосистему, в основном они действуют, хотя и теряют свою значимость.
- person Maarten Bodewes; 10.09.2020
Чтобы уточнить, стандарт PKCS # 5, версия 2.0 RFC 2898 и 2.1 RFC 8018 оставляют кодировку символов для паролей явно неуказанной, но, в интересах взаимодействия используйте общие правила, например ASCII или UTF-8. Хорошо спроектированный API либо использует массив байтов, либо позволяет вызывающей стороне указывать кодировку символов.
- person Charlie Reitzel; 29.06.2021
Использование spongycastle (java на android)
Замените spongycastle на bouncycastle, если вы напрямую используете bouncycastle на java.
import org.spongycastle.crypto.generators.PKCS5S2ParametersGenerator;
import org.spongycastle.crypto.digests.SHA256Digest;
import org.spongycastle.crypto.params.KeyParameter;
public class Crypto {
public String pbkdf2(String secret, String salt, int iterations, int keyLength) {
PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(new SHA256Digest());
byte[] secretData = secret.getBytes();
byte[] saltData = salt.getBytes();
gen.init(secretData, saltData, iterations);
byte[] derivedKey = ((KeyParameter)gen.generateDerivedParameters(keyLength * 8)).getKey();
return toHex(derivedKey);
}
private static String toHex(byte[] bytes) {
BigInteger bi = new BigInteger(1, bytes);
return String.format("%0" + (bytes.length << 1) + "x", bi);
}
}
person
Guillaume Vincent
schedule
05.12.2018