Может ли значение из узла crypto.createCipheriv ('aes-256-gcm', ...). GetAuthKey () быть publi c? - PullRequest
2 голосов
/ 17 июня 2020

У меня проблемы с поиском информации. Кто-нибудь знает, может ли значение, возвращаемое из cipher.getAuthTag () (-> возвращает MA C) , быть общедоступным?

TL ; DR

Может ли код аутентификации сообщения быть общедоступным или его нужно держать в секрете, например, пароль?

Некоторые предыстории, я пытаюсь чтобы зашифровать файл. Я нашел этот вопрос и ответ о стеке, которые помогли мне начать работу. { ссылка }

Проведя небольшое исследование документации nodejs, я обнаружил, что в ответе используется устаревшая функция. createCipher . Новая функция для использования должна быть createCipheriv .

Итак, чтобы использовать новый createCipheriv, я использовал документацию, чтобы написать новую функцию шифрования и дешифрования, аналогичную той, что в посте, используя новая функция createCipheriv. После написания функции дешифрования я получил сообщение об ошибке:

Ошибка: неподдерживаемое состояние или невозможность аутентификации данных

После поиска в Google этой проблемы это привело меня к этому сообщение на github . Вкратце, он сказал, что authTag, сгенерированный с помощью шифра, необходим для расшифровки файла.

Я не знал, что это за authTag, и никто из моих знакомых тоже. Я начал гуглить, и это позволило мне перейти к этой записи в блоге . В нем указано

authTag - это код аутентификации сообщения (MA C), вычисленный во время шифрования.

А вот статья в Википедии что такое код аутентификации сообщения.

Итак. Вот мой вопрос. Может ли код аутентификации сообщения быть общедоступным или его нужно хранить в секрете, как пароль? 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 Ответ

3 голосов
/ 18 июня 2020

Да. MA C считается publi c.

Как правило, коды аутентификации сообщений считаются publi c. Код аутентификации сообщения аутентифицирует (зашифрованное) сообщение под указанным вами ключом. Другими словами, он используется получателем, чтобы проверить, не изменился ли зашифрованный текст во время передачи. В вашей ситуации, пока ключ остается секретным, злоумышленник не может использовать MA C.

MA C обычно помещается рядом с зашифрованным текстом, когда зашифрованный текст сохраняется ( точно так же, как IV).


Кстати, в вашем случае вы are случайным образом генерировали IV. Это нормально, но имейте в виду, что количество сообщений, которые можно безопасно зашифровать с помощью одного и того же ключа, весьма мало . Если IV используется для нескольких сообщений (даже одного!), Полная безопасность этой схемы нарушается. На самом деле, вы, вероятно, захотите это:

const iv = crypto.randomBytes(12);
...