Я использую Java для шифрования текстовой полезной нагрузки с помощью Triple DES. Сначала я создаю эфемерный ключ, который буду использовать для шифрования полезной нагрузки:
private byte[] createEphemeralKey() throws Exception {
KeyGenerator keygen = KeyGenerator.getInstance("DESede");
keygen.init(168);
return keygen.generateKey().getEncoded();
}
Затем я шифрую свою полезную нагрузку указанным ключом:
private String encryptTripleDES(byte[] ephemeralKey, String payload) throws Exception {
Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(ephemeralKey, "DESede"));
byte[] plainTextBytes = payload.getBytes();
byte[] cipherText = cipher.doFinal(plainTextBytes);
return Base64.getEncoder().encodeToString(cipherText);
}
Также нужна функция заполнения, чтобы длина данных делилась на 8:
private String adjustPadding(String input, int blockSize) {
int len = input.length() % blockSize;
int paddingLength = (len == 0) ? 0 : (blockSize - len);
while (paddingLength > 0) {
input += "F";
paddingLength--;
}
return input;
}
И вот мой процесс от начала до конца:
String data = "Marnus"
byte[] = ephemeralKey = createEphemeralKey();
String adjustedData = adjustPadding (data,8);
String encryptedPayload = encryptTripleDES(ephemeralKey, adjustedData);
String encodedKey = Base64.getEncoder().encodeToString(ephemeralKey)
Итак, я беру две переменные encryptedPayload
и encodedKey
, которые являются строками в кодировке Base64, и отправляю их через HTTP в экспресс-приложение узла.
Что касается Javascript, я использую node-forge. Вот часть моего экспресс-приложения, которое выполняет расшифровку:
let nodeBuffer = Buffer.from(data, 'base64')
let input = forge.util.createBuffer(nodeBuffer.toString('binary'))
// 3DES key and IV sizes
let keySize = 24;
let ivSize = 8;
let derivedBytes = forge.pbe.opensslDeriveBytes(ephemeralKey, null, keySize + ivSize);
let buffer = forge.util.createBuffer(derivedBytes);
let key = buffer.getBytes(keySize)
let iv = buffer.getBytes(ivSize)
let decipher = forge.cipher.createDecipher('3DES-ECB', key)
decipher.start({iv: iv})
decipher.update(input)
console.log('decipher result', decipher.finish())
let decryptedResult = decipher.output.data;
Вот пример Triples DES в документации node-forge:
Несколько замечаний: я создаю буфер node-forge из обычного буфера, поскольку у меня нет входного файла, как в примерах. Вот как в документах говорится, что нужно создавать один буфер из другого:
* Я использую base64, так как это то, что я использовал на стороне java для кодирования отправленных данных.
Затем у меня нет соли, поэтому я оставил 2-й параметр null
в opensslDeriveBytes
, как указано в документах, которые я должен сделать.
В-третьих, я также не уверен, что мой размер ключа 24 правильный?
Мои результаты
Таким образом, выполнение сквозного теста дает следующее:
В моем приложении Java тестовые данные были "Marnus"
, encryptedPayload
были ez+RweSAd+4=
, а encodedKey
были vCD9mBnWHPEBiQ0BGv7gc6GUCOoBgLCu
.
Затем в моем коде javascript data
было, очевидно, ez+RweSAd+4=
(encryptedPayload), а ephemeralKey
было vCD9mBnWHPEBiQ0BGv7gc6GUCOoBgLCu
(encodedKey).
После запуска расшифровки значение decryptedResult
было ©ýÕ?µ{'
, что, очевидно, просто мусор, поскольку оно еще не было закодировано, но я не могу понять, какую кодировку использовать?
Я пытался использовать forge.util.encode64(decipher.output.data)
, но это дало мне только qf3VP7UYeyc=
, что неправильно.
Что бы это ни стоило, вот тот тип, который decipher.output
NoPadding
). Тогда длина открытого текста должна быть целым числом, кратным размеру блока (8 байтов для 3DES). Но открытый текстMarnus
имеет длину всего 6 байт. Это вызывает ошибку времени выполнения. Кроме того, кодировка не определена при кодировании (getBytes(???)
). Исправьте эти проблемы для определенной отправной точки. Спасибо. - person user 9014097   schedule 23.09.2020