Может ли значение из узла crypto.createCipheriv('aes-256-gcm', ...). GetAuthKey() быть общедоступным?
У меня проблемы с поиском информации. Кто-нибудь знает, может ли значение, возвращаемое cipher.getAuthTag() (-> возвращает MAC), быть общедоступным?
TL;DR
Может ли код аутентификации сообщения быть общедоступным или его нужно хранить в секрете, как пароль?
Некоторая предыстория, я пытаюсь зашифровать файл. Я нашел этот вопрос и ответ о стеке, которые помогли мне начать работу. /questions/7197268/nodejs-shifruet-bolshoj-fajl-ispolzuya-aes/7197272#7197272
Проведя небольшое исследование документации nodejs, я обнаружил, что в ответе используется устаревшая функция. createCipher. Новая функция должна быть createCipheriv.
Итак, чтобы использовать новый createCipheriv, я использовал документацию для написания новой функции шифрования и дешифрования, аналогичной той, что в посте, с использованием новой функции createCipheriv. После написания функции дешифрования я получил ошибку, которая была
Ошибка: неподдерживаемое состояние или невозможность аутентификации данных
После поиска в Google этой проблемы я перешел к этой публикации на github. Вкратце, он сказал, что authTag, сгенерированный с помощью шифра, необходим для расшифровки файла.
Я не знал, что это за authTag, и никто из моих знакомых тоже. Я начал гуглить, и это позволило мне попасть в этот блог. Здесь утверждается
AuthTag - это код аутентификации сообщения (MAC), вычисленный во время шифрования.
А вот статья в Википедии о том, что такое код аутентификации сообщения.
Так. Вот мой вопрос. Может ли код аутентификации сообщения быть общедоступным или его нужно хранить в секрете, как пароль?
Мой код не так актуален, но может помочь кому-то создать шифрование и дешифрование с помощью createCipheriv и createDecipheriv.
Шифрование
const crypto = require('crypto');
const fs = require('fs');
// const iv = crypto.randomBytes(32).toString('hex');
// EDIT - based on @President James K. Polk. The initialization vector should be 12 bytes long
// const iv = crypto.randomBytes(6).toString('hex');
// EDIT - based on @dsprenkels. I misunderstood @President James K. Polk
const iv = crypto.randomBytes(12).toString('hex');
const privateKey = 'private key that is 32 byte long';
const cipher = crypto.createCipheriv('aes-256-gcm', privateKey, iv);
const filename = 'somefile.txt';
const encFilename = 'somefile.txt.enc';
const unencryptedInput = fs.createReadStream(filename);
const encryptedOutput = fs.createWriteStream(encFilename);
unencryptedInput.pipe(cipher).pipe(encryptedOutput);
encryptedOutput.on('finish', () => {
const authTagAsHex = cipher.getAuthTag().toString('hex'); // <-- can this be public
console.log(authTagAsHex);
});
Расшифровка
const crypto = require('crypto');
const fs = require('fs');
// const publicIV = 'same iv generated during encryption crypto.randomBytes(32).toString("hex")';
// EDIT - based on @President James K. Polk. The initialization vector should be 12 bytes long
// const publicIV = 'same iv generated during encryption crypto.randomBytes(6).toString("hex")';
// EDIT - based on @dsprenkels. I misunderstood @President James K. Polk
const publicIV = 'same iv generated during encryption crypto.randomBytes(12).toString("hex")';
const authTag = 'same authKey generated from cipher.getAuthTag().toString("hex")';
const privateKey = 'private key that is 32 byte long';
const decipher = crypto.createDecipheriv('aes-256-gcm', privateKey, publicIV);
decipher.setAuthTag(Buffer.from(authTag, 'hex'));
const filename = 'somefile.txt';
const encFilename = 'somefile.txt.enc';
const readStream = fs.createReadStream(encFilename);
const writeStream = fs.createWriteStream(filename);
readStream.pipe(decipher).pipe(writeStream);
1 ответ
Да. MAC считается публичным.
Обычно коды аутентификации сообщений считаются общедоступными. Код аутентификации сообщения аутентифицирует (зашифрованное) сообщение с использованием предоставленного вами ключа. Другими словами, он используется получателем, чтобы проверить, не изменился ли зашифрованный текст во время передачи. В вашей ситуации, пока ключ остается секретным, злоумышленник не может использовать MAC.
MAC обычно ставится рядом с зашифрованным текстом, когда зашифрованный текст сохраняется (как и IV).
Кстати, в вашем случае будут случайным образом генерировать IV. Это нормально, но имейте в виду, что количество сообщений, которые можно безопасно зашифровать одним и тем же ключом, довольно мало. Если IV используется для нескольких сообщений (даже одного!), Полная безопасность этой схемы нарушается. На самом деле вы, вероятно, захотите этого:
const iv = crypto.randomBytes(12);