crypto privateDecrypt на стороне клиента - PullRequest
0 голосов
/ 24 апреля 2020

Я разработал веб-приложение с Express и React для проведения онлайн-экзаменов с использованием асимметричной c криптографии для обеспечения безопасности. он должен зашифровать объект вопроса, отправляемый клиентской стороне, а затем расшифровать его с помощью privateKey пользователя. ответы пользователя также должны быть зашифрованы, а затем отправлены на сервер. Я использовал модуль криптоузла на стороне клиента, и он работает только для симметрии c enc / de c, а не асимметрии c и говорит Unable to decrypt data. Я нашел модуль npm для клиентской стороны, но он не работал, и те не могут расшифровать данные (privateDecrypt). Кроме того, я попытался использовать WebCryptoApi, но это заканчивается просто ошибка DOMException.

, если вы можете, пожалуйста, помогите мне найти способ сделать это.

ОБНОВЛЕНИЕ (КОД)

examController. js

static examStarted(req, res) {
let userInfo = this._userToken(req, res);
console.log(userInfo);
let examID = 1;
exam
  .findAll({
    attributes: ["id", "idCourse", "totalQuestion"],
    where: {
      id: examID,
    },
    include: [
      {
        model: userRegisterToExam,
        attributes: ["id"],
        required: true,
        where: {
          idUser: userInfo.id,
        },
      },
      {
        model: course,
        attributes: ["id"],
        required: true,
        include: [
          {
            model: question,
            required: true,
          },
        ],
      },
    ],
  })
  .then((responses) => {
    const array = [];
    const MyQuestion = [];
    const questionInfo = [];
    const lenghtofQuestion = Object.keys(responses[0].course.questions)
      .length;
    console.log(lenghtofQuestion);
    const info = responses[0].course.questions;

    //this.generateQuestion(req, res, queryResult1[0].idCourse)
    for (let total = 0; total <= responses[0].totalQuestion - 1; total++) {
      const count = this.RandomInt(lenghtofQuestion, array);
      console.log(count);
      MyQuestion[total] = info[count];
      questionInfo.push({
        idExamStart: 0,
        idQuestion: info[count].id,
        response: 5,
        status: 0,
      });
      array.push(count);
    }
    //console.log(responses[0].userRegisterToExam)

    this.startTest(
      req,
      res,
      MyQuestion,
      questionInfo,
      examID,
      responses[0].userRegisterToExams[0].id
    );
  })
  .catch((error) => this.SetErrorInfo(req, res, error));
}
static startTest(
req,
res,
MyQuestion,
questionInfo,
examID,
idUserRegisterToExam
) {
let userInfo = this._userToken(req, res);
let password = "milad"; //userInfo.id + "-" + this.generateRandomString();
console.log("pass1", password);
let key = this.generateKeys(password);
let publicKey = key.publicKey;
let privateKey = key.privateKey;
let data = {
  idUser: userInfo.id,
  idExam: examID,
  idUserRegisterToExam,
  dateStart: this.getDate("jYYYY/jMM/jDD h:m:s"),
  dateUpload: "",
  teacherConfirmation: "0",
  supervisorConfirmation: "0",
  score: "0",
  document: "0",
  status: "0",
  public: publicKey,
  private: privateKey,
  password,
};
examStart
  .create(data)
  .then((responses) => {
    let tokenString = {
      userID: userInfo.id,
      start: responses.id,
      password,
      privateKey,
    };
    let d = this.encryption(
      JSON.stringify(MyQuestion),
      publicKey,
      privateKey,
      password
    );

    let data = {
      token: this.encrypt(JSON.stringify(tokenString)),
      data: d.data,
      k: d.key,
    };
    res.send(data);
  })
  .catch((error) => this.SetErrorInfo(req, res, error));
}
static encryption(toEncrypt, publicKey, privateKey, password) {
var mykey = crypto.createCipher("aes-128-cbc", password);
var mystr = mykey.update(toEncrypt, "utf8", "base64");
mystr += mykey.final("base64");
// key encryption (asymmetric)
var buffer = new Buffer(password);
var encrypted = crypto.publicEncrypt(publicKey, buffer);
var enc = encrypted.toString("base64");
return { key: encrypted.toString("base64"), data: mystr };
}

static decryption(req, res) {
// decryption
// key decryption (asymmetric)
let dec = this.decrypt(req, res, req.body.token);
console.log("dec", dec);
let tokenObject = JSON.parse(dec);
let privateKey = tokenObject.privateKey;
let password = tokenObject.password; //this.decrypt(req, res, tokenObject.password);
let pass = password.toString("utf8");
let buffer = new Buffer(req.body.key, "base64");
const decryptedKey = crypto.privateDecrypt(
  {
    key: privateKey.toString(),
    passphrase: pass,
  },
  buffer
);
var symmetricKey = decryptedKey.toString("utf8");
// symmetric decryption
var mykey = crypto.createDecipher("aes-128-cbc", symmetricKey);
var mystr = mykey.update(req.body.data, "base64", "utf8");
mystr += mykey.final("utf8");
res.send({ requests: req.body, result: mystr });
}
static generateKeys(myPassword) {
const { publicKey, privateKey } = crypto.generateKeyPairSync("rsa", {
  modulusLength: 4096,
  namedCurve: "secp256k1",
  publicKeyEncoding: {
    type: "spki",
    format: "pem",
  },
  privateKeyEncoding: {
    type: "pkcs8",
    format: "pem",
    cipher: "aes-256-cbc",
    passphrase: myPassword,
  },
});
return {
  privateKey,
  publicKey,
};
}

React Component (получение зашифрованных вопросов с сервера)

_getData() {
const data = {
  exam: this.state.id,
  idCourse: this.state.idCourse,
  factor: this.state.idFactor,
};

axios
  .post(`${this._ServerUrl()}examStarted`, data, {
    headers: this._Header(),
  })
  .then((response) => {
    let a = this.decrypt(response.data.token); // it's for symmetric decryption and works good.
    console.log(a);
    this.setState({
      privateKey: a.privateKey,
      password: a.password,
      getDateStatus: true,
    });
    try {
      let data = this.decryption(
        a.password,
        a.privateKey,
        response.data.data,
        response.data.k
      );
      console.log(data);
    } catch (error) {
      console.log(error);
    }
  })
  .catch((error) => {
    this.errorLog(error);
  });
}


decryption(password, privateKey, text, key) {
let buffer = new Buffer(key, "base64");
const decryptedKey = cryptoBrowserify.privateDecrypt(
  {
    key: privateKey.toString(),
    passphrase: password.toString(),
  },
  buffer
);
var symmetricKey = decryptedKey.toString("utf8");
// symmetric decryption
var mykey = crypto.createDecipher("aes-128-cbc", symmetricKey);
var mystr = mykey.update(text, "base64", "utf8");
mystr += mykey.final("utf8");
return mystr;
}
...