Как говорится в названиях, я хотел бы знать, как наилучшим образом использовать экземпляр Cipher в многопоточной среде с учетом алгоритма RSA.Безопасность потоков с RSA Cipher
Я прочитал несколько вопросов по данной теме, а также от того, что я собрал:
Cipher не поточно, поскольку она поддерживает внутреннее состояние во время шифрования/дешифрования
, если AES является используется, то
doFinal()
будут сброшены вектор инициализации, чтобы последний известное значение, и поэтому новый экземпляр Cipher должен быть сформирован каждый раз, когда
Мои вопросы
Это хорошо, чтобы вызвать
cipher.init()
только один раз, если выбран алгоритм RSA? Это противоречит второму пулю, как показано в нижеследующем коде. Я считаю, что нет никакого вектора инициализации. Кроме того, шифр будет использоваться только для дешифрования данных.Должен ли я синхронизироваться только на вызове
cipher.doFinal()
?- Каков общий способ обработки нескольких потоков, запрашивающих службы криптографии, должен ли я иметь пул шифров в качестве блокирующей очереди за некоторым прокси-сервером?
Пример кода:
public class RsaPrototype {
private static PrivateKey privKey;
private static Cipher cipher;
private static final String PRIVATE_KEY_PATH ="./privK.pem";
/*
* ALGORITHM/BLOCKING_MODE/PADDING_SCHEMA
*/
private static final String CIPHER_SPECIFICATION = "RSA/None/NoPadding";
private static final String RSA_PROVIDER ="BC";
static {
Security.addProvider(new BouncyCastleProvider());
importPrivateKey();
cipher = getCipher();
}
/**
* Initializes cipher with RSA algorithm, without blocking mode and padding.
* Implementation provider is bouncy castle.
*
* @return cipher instance.
*/
private static Cipher getCipher() {
try
{
Cipher cipher = Cipher.getInstance(CIPHER_SPECIFICATION, RSA_PROVIDER);
cipher.init(Cipher.DECRYPT_MODE, privKey);
return cipher;
} catch (NoSuchAlgorithmException | NoSuchPaddingException | NoSuchProviderException e) {
throw new RuntimeException(e.getMessage());
}
}
/**
* Imports public key from the given .PEM file into application cache.
*/
private static void importPrivateKey() {
try (BufferedReader reader =
new BufferedReader(new FileReader(PRIVATE_KEY_PATH));
PEMParser pemParser =
new PEMParser(reader);) {
privKey = new JcaPEMKeyConverter().getPrivateKey((PrivateKeyInfo) pemParser.readObject());
}
catch (IOException ignorable) {
// not handled
}
}
public static String decrypt(byte[] encryptedText) {
byte[] plainText;
synchronized (cipher) {
plainText = cipher.doFinal(encryptedText);
}
return new String(plainText, StandardCharsets.UTF_8);
}
}
Как получить метод, который «делает материал» с 'Cipher' вместо этого (например, метод' encrypt() 'для шифрования чего-то)? –
Я забыл вставить его O_O – John
Сколько будет конкуренции? Первое, что я хотел бы сделать, - это сериализовать доступ, сделав его «синхронизированным» и протестировать, если это будет работать достаточно хорошо. –