Имею следующее:
let original = 'something'
let passphrase = uuidv4()
// will take place on the server
let encrypted = CryptoJS.AES.encrypt(original, passphrase)
// will take place on the browser
// I want this part to take ≈ 10 minutes *minimum*
let decrypted = CryptoJS.AES.decrypt(encrypted, passphrase)
Я пробовал итеративный подход. Управление необходимыми итерациями дешифрования означает, что вы также можете до некоторой степени контролировать время дешифрования:
// increase this until we reach the desired decryption time on the browser
let numberOfEncryptions = 2
// will take place on the server
let encrypted = CryptoJS.AES.encrypt(original, passphrase).toString()
let i = 0
while (i < numberOfEncryptions) {
encrypted = CryptoJS.AES.encrypt(encrypted, passphrase).toString()
i++
}
// will take place on the browser:
let decrypted = CryptoJS.AES.decrypt(encrypted, passphrase).toString(CryptoJS.enc.Utf8)
i = 0
while (i < numberOfEncryptions) {
decrypted = CryptoJS.AES.decrypt(decrypted, passphrase).toString(CryptoJS.enc.Utf8)
i++
}
await checkWithServer(decrypted) // returns true
Результаты были неутешительными.
Увеличение количества шифрований на сервере также увеличивает время дешифрования в браузере, и это здорово, потому что это то, что я хочу.
Но это также увеличивает размер зашифрованного файла в геометрической прогрессии, что ужасно, поскольку пользователь не может загрузить такой огромный файл, чтобы его расшифровать.
Есть ли другое решение?
Обновлено:
@SlavaKnyazev предложил мне вместо этого зашифровать парольную фразу, используемую для шифрования данных, и отправить намекать конечному пользователю, чтобы он перебрал парольную фразу.
Вместо того, чтобы тратить время на расшифровку самих данных, пользователь будет тратить время на перебор парольной фразы.
Вот как я пытался это реализовать (в качестве теста):
const KEY = 'ab' // uuidv4()
const dataToEncrypt = 'The Message'
const md5key = CryptoJS.MD5(KEY).toString()
const encrypted = CryptoJS.AES.encrypt(dataToEncrypt, md5key)
const sha1keyHint = CryptoJS.SHA1(KEY).toString()
let pool = 'abcdefghijklmnopqrstuvwxyz'.split('')
let before = Date.now()
let after
let md5keyFromHint
bruteForce(pool, (value) => {
if (CryptoJS.SHA1(value).toString() === sha1keyHint) {
md5keyFromHint = CryptoJS.MD5(value).toString()
after = Date.now()
console.info(`KEY is ${value}`)
console.info(`Found after ${(after - before) / 1000} seconds`)
return true
}
return false
})
const decrypted = CryptoJS.AES.decrypt(encrypted, md5keyFromHint).toString(CryptoJS.enc.Utf8)
console.info(dataToEncrypt === decrypted) // returns true
Оказывается, KEY должен быть довольно "простым", а не uuidv4(), как я думал изначально. В противном случае это может занять вечность. Кроме того, для метода грубого принуждения, который я использую, требуется «пул» персонажей, на который нужно обратить внимание, я думаю, чем больше пул, тем больше времени на это потребуется.
Еще раз моя проблема в том, что пользователь не будет тратить время на расшифровку фактических данных. Это похоже на PoW, то есть на подделку.
Но на этот раз я рассмотрю вопрос, на который будет дан ответ, и остановлюсь на этом. :-)
Моя первоначальная цель, по-видимому, не достижима. Спасибо за помощь.
Думаю, вы не приняли близко к сердцу Совет Рани из предыдущего вопроса: «Не сообщайте пользователю полную парольную фразу для дешифрования. Дайте только частичный ключ и заставьте его угадать / найти остальную часть ключа».
Я сделал это, но требование, предъявленное мне сейчас, - это минимальный срок. Как мне это контролировать, независимо от того, какие данные я прошу расшифровать? Надеюсь, этот формат сообщения более понятен, а не просто дубликат :)
@SlavaKnyazev Я обновил подробности



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Не давайте ключ, дайте хеш ключа. Длина ключа к грубой силе даст вам требуемую степень детализации.
Процесс шифрования:
Чем длиннее ключ, тем экспоненциально больше времени потребуется на его поиск, при этом размер полезной нагрузки остается постоянным.
Однако в этом есть недостаток - брутфорс не нужен, так как брутфорс для шифрования AES будет столь же простым делом. Этого можно избежать, сделав ключ также хешем.
Зашифруйте свои данные не с помощью «hunter2», а с помощью MD5(hunter2) (используйте другой алгоритм).
Добавьте немного соли в хеши, чтобы предотвратить эффективное использование радужных таблиц.
Псевдокод:
// Encrypt
let key = "password";
let aesKey = md5(password);
let hint = sha1(password);
let encryptedData = data.encrypt(aesKey);
let decryptedData = data.decrypt(md5(bruteForceSha1(hint));
Не могли бы вы предоставить мне короткий пример (на Javascript), если возможно, где ключ, переданный пользователю, затем подвергается брутфорсу (каким-либо методом), а время, необходимое для завершения брутфорса, составляет около 10-20 минут. средний браузер / машина. Если это слишком много, я приму ваш ответ, несмотря ни на что :-) (Я не буду снова спрашивать о другом OP - и извините за шум)
Мои знания CryptoJ очень ограничены
Как мне «Добавить соль в хеши»? Также есть ли хороший модуль перебора Js для проверки этого? :)
Солить хэш означает добавить к значению константу. Это связано с тем, что хеш-значение hunter2 хорошо известно и его можно найти в базах данных. Хеш-значение «hunter2sfsavvgdarfsaf» - нет.
Я думал, что мой исходный ключ / кодовая фраза (ваш let key = "password" в вашем примере) на самом деле может быть let key = uuidv4(). Нужна ли мне еще соль в этом случае?
Кроме того, когда вы применяете грубую силу для чего-то, вам нужно каждый раз проверять, нашли ли вы ключ или нет. Как клиент будет проверять каждый раз каждый цикл перебора? Делать запрос к серверу каждый раз? Это много запросов? Идея заключалась в том, чтобы дешифрование происходило в браузере без какой-либо связи с сервером, прежде чем это будет сделано, иначе производительность была бы очень плохой. Если я все еще не упускаю идею, лежащую в основе решения для брутфорса
Я обновил OP с моими проблемами: - /
Обновил OP в последний раз. Думаю, теперь я понял, что вы имели в виду.
Хеши обрабатываются локально, никаких запросов делать не нужно.
Не могли бы вы подробнее рассказать о Зачем, который вам нужен? Могут быть способы получше.