Следующая Java создает зашифрованные данные:
private static final int KEY_LENGTH = 256;
private static final int ITERATION_COUNT = 65536;
public static String encrypt(String strToEncrypt, String secretKey, String salt) {
try {
SecureRandom secureRandom = new SecureRandom();
byte[] iv = new byte[16];
secureRandom.nextBytes(iv);
IvParameterSpec ivspec = new IvParameterSpec(iv);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(secretKey.toCharArray(), salt.getBytes(), ITERATION_COUNT, KEY_LENGTH);
SecretKey tmp = factory.generateSecret(spec);
SecretKeySpec secretKeySpec = new SecretKeySpec(tmp.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivspec);
byte[] cipherText = cipher.doFinal(strToEncrypt.getBytes("UTF-8"));
byte[] encryptedData = new byte[iv.length + cipherText.length];
System.arraycopy(iv, 0, encryptedData, 0, iv.length);
System.arraycopy(cipherText, 0, encryptedData, iv.length, cipherText.length);
return Base64.getEncoder().encodeToString(encryptedData);
} catch (Exception e) {
// Handle the exception properly
e.printStackTrace();
return null;
}
}
Запускаем это следующим образом:
encrypt( "Hello, this is a secret message.", "MySecretKey", "MySalt");
Дает результат:
zYsUELxuE3KT4IDa1cbRnX70OSlQTbcDa1LEuh0IzfjZZcJhnuX8kLFcGqYLWjfp0XJzfgwFreZIqmqE1HqlGw==
Я сохраняю это в файл и теперь хочу использовать openssl для его расшифровки.
Я использовал различные варианты с openssl, но, похоже, не могу заставить его работать, например:
echo -n MySalt | od -A n -t x1 | perl -lpe's,\s+,,g'
4d7953616c74
openssl enc -e -aes-256-cbc -k MySecretKey -S 4d7953616c74 -md sha256 -in file.in
hex string is too short, padding with zero bytes to length
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
openssl enc -e -aes-256-cbc -k MySecretKey -S 4d7953616c74 -iter 65536 -md sha256 -in file.in
hex string is too short, padding with zero bytes to length
z....garbage..........
Я не могу найти правильную комбинацию опций для openssl.




(Не программирование или разработка)
Во-первых, enc -e (или по умолчанию) — шифрование; -d — расшифровка. Кроме того, enc ожидает (и помещает) соль в начало файла, но не ожидает (или не помещает) IV, и по умолчанию он не выполняет PBKDF2 и извлекает IV в дополнение к ключу. И только версия 3.2.0 (то есть выпущенная за последние несколько месяцев) может использовать длину соли, отличную от традиционной 8. Но все, начиная с версии 1.1.0 в 2016 году, по умолчанию использует SHA256 для хеша.
Итак, если у вас установлена версия 3.2.0:
$ echo zYsUELxuE3KT4IDa1cbRnX70OSlQTbcDa1LEuh0IzfjZZcJhnuX8kLFcGqYLWjfp0XJzfgwFreZIqmqE1HqlGw== | \
> openssl base64 -d -A >78319330.bin
$ iv=$( head -c16 78319330.bin |xxd -p ) # or if no xxd, something like your od+sed
$ ( printf Salted__MySalt; tail -c+17 78319330.bin ) | \
> openssl enc -d -aes-256-cbc -k MySecretKey -pbkdf2 -iter 65536 -saltlen 6 -iv $iv
Hello, this is a secret message.
Спасибо, это сработало для приведенного выше примера, но у меня возникла проблема с попыткой использовать это для шифрования двоичного/zip-файла, для которого я задам отдельный вопрос.
@ProWest: соль не позволяет злоумышленнику предварительно вычислить один словарь или радужную таблицу для одновременной атаки на несколько хешей, таких как пароли миллионов пользователей, или обнаружения повторяющихся паролей среди таких групп; это не обязательно должно быть секретным, и обычно это не так. См. en.wikipedia.org/wiki/Salt_(cryptography) или crypto.stackexchange.com.
Я тоже новичок в этом, и из любопытства и удивления мне кажется, что соль можно извлечь из самого файла, так как же наличие соли делает его более безопасным, чем просто ключ/пароль?