Создать и проверить сеанс в node.js - PullRequest
4 голосов
/ 12 февраля 2020

Каков правильный способ генерации сеанса и чем проверять его при каждом запросе?

Регистрация и первоначальная аутентификация (проверка личности пользователя для генерации сеанса) обрабатывается внешней службой, поэтому об этом не может быть и речи.

Чтобы упростить вопрос, каков собственный безопасный способ создания и шифрования сеанса с секретом.


Требования (альтернативы приветствуются) :

  • Сессия должна состоять из двух частей: одна хранится в файлах cookie, вторая - в базе данных.
  • Проверка пользователя обрабатывается сервером с использованием части сеанса базы данных, части куки и функции проверки.
  • Функции создания и проверки сеансов, хранящиеся на стороне сервера и недоступные для пользователя.
  • Если часть или функции сеанса базы данных скомпрометированы, хакер не может сделать запрос, выдавая себя за пользователя. Для этого ему нужно будет украсть пользовательские файлы cookie или функцию создания сеанса и часть сеанса базы данных.
  • Поддержка нескольких устройств с одной и той же частью сеанса базы данных.
  • JWT не может использоваться, поскольку требуется выход из системы на сервере сторона (часть сеанса базы данных будет удалена, и все устройства не смогут войти со старой частью сеанса файлов cookie). У пользователя был некоторый уровень доверия, который может измениться, и это потребует аннулирования JWT, поэтому сеансы - лучший выбор.

Я думал об использовании Crypto AES для этого, но после спрашивал "все ли в порядке?" ?"- ответ был" нет ", я не специалист по криптографии, поэтому я не до конца понял причину.

Вот моя первоначальная идея реализации:

/**
 * @param {string} data dummy
 * @param {string} userKey from database or create new
 * @return {object} {iv, key, encryptedData}
 */
function encrypt(data, userKey) {
  let key = userKey ? Buffer.from(userKey, 'hex') : crypto.randomBytes(32)
  let iv = crypto.randomBytes(16)
  let cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(key), iv)
  let encrypted = cipher.update(data)
  encrypted = Buffer.concat([encrypted, cipher.final()])
  return { iv: iv.toString('hex'), key: key.toString('hex'), encryptedData: encrypted.toString('hex') }
}

/**
 * @param {string} iv
 * @param {string} key
 * @param {string} encryptedData
 * @return {string} decrupted dummy data
 */
function decrypt(iv, key, encryptedData) {
  try {
    iv = Buffer.from(iv, 'hex')
    key = Buffer.from(key, 'hex')
    encryptedData = Buffer.from(encryptedData, 'hex')
    let decipher = crypto.createDecipheriv('aes-256-cbc', key, iv)
    let decrypted = decipher.update(encryptedData)
    decrypted = Buffer.concat([decrypted, decipher.final()])
    return decrypted.toString()
  } catch (err) {
    return false
  }
}

1 Ответ

1 голос
/ 20 февраля 2020

Можно сделать так, чтобы пользователь генерировал RSA и использовал crypto с publi c и закрытыми ключами, но ключ publi c всегда должен отправляться пользователем («устройство») )

    'use strict';
const express = require('express');
const fs = require('fs');
const nodersa = require('node-rsa');
const bodyParser = require('body-parser');

let app = express();
app.use(bodyParser.urlencoded({ extended : false }));
app.use(bodyParser.json());
// req.body.value is public key, this never write in database or file
app.post('/', (req, res)=>{
    let value = req.body.value; 
    const privateKey = fs.readFileSync('./store/privateKey.pem', 'utf8');
    const original = new nodersa(privateKey).decrypt(value, 'utf8');
    res.end(original);
});

app.listen(8000, ()=>{
    console.log('on 8000');
});

если вы используете publi c центр сертификации с узлом, используйте дополнительный файл с именем «файл сертификации», пример узла здесь , этот файл выдается C .A. Вы могли бы работать как C .A. и сгенерируйте этот файл, но он рекомендуется для закрытых систем, если вам не нужно губернаторское разрешение

...