Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

76
Visualizações
how to show error when wrong password is given NodeJS crypto - createDecipheriv and pbkdf2

Created a simple app that encrypts text, but how do i show error when wrong password or salt is given. Hosted it on replit. But when i give wrong password or salt it just decrypts it. There isn't a callback or function in crypto for crypto.createDecipheriv()

const app = {
  encrypt(text, password, salt) {
    password = password.repeat(32).substr(0, 32);
    salt = salt.repeat(16).substr(0, 16);
    crypto.pbkdf2(password, salt, 10, 16, 'sha512', (err, key) => {
      if (err) {
        console.log(err); 
      } else {
        key = key.toString('hex');
        const cipher = crypto.createCipheriv('aes-256-gcm', key, salt);
        let encrypted = cipher.update(text, 'utf8', 'hex');
        console.log(encrypted);
      }
    });
  },
  decrypt(text, password, salt) {
    password = password.repeat(32).substr(0, 32);
    salt = salt.repeat(16).substr(0, 16);
    crypto.pbkdf2(password, salt, 10, 16, 'sha512', (err, key) => {
      if (err) {
        console.log(err); 
      } else {
        key = key.toString('hex');
        const cipher = crypto.createDecipheriv('aes-256-gcm', key, salt);
        let decrypted = cipher.update(text, 'hex', 'utf8');
        console.log(decrypted);
      }
    });
  }
}

const message = 'Hello World';
app.encrypt(message, 'password', 'salt');

const cipherText = 'a0a4e0ad97133494856502';
app.decrypt(cipherText, 'password', 'salt');
about 4 years ago · Santiago Gelvez
1 Respostas
Responde à pergunta

0

GCM generates an authentication tag (16 bytes by default) during encryption, which is used for authentication during decryption.
Some libraries (e.g. Java) implicitly concatenate ciphertext and tag (ciphertext|tag) during encryption and implicitly separate both during decryption (this is not critical since the tag is not secret).
The crypto module of NodeJS, on the other hand, handles ciphertext and tag independently, so the tag must be considered explicitly. It can be determined during encryption with getAuthTag() and must be set during decryption with setAuthTag(). Both is missing in the posted code.
Also missing are the final() calls that generate the tag on encryption and perform authentication on decryption.
To pass the tag to the decryption in this example, the following fix concatenates the tag with the ciphertext during encryption and separates it during decryption (following the Java pattern).

If these problems are fixed, the decryption works for correct data and displays a corresponding message for incorrect data: Error: Unsupported state or unable to authenticate data.

Fixed code, see the comments for details:

const crypto = require('crypto');

const app = {
  encrypt(text, password, salt) {
    password = password.repeat(32).substr(0, 32);
    salt = salt.repeat(16).substr(0, 16);
    crypto.pbkdf2(password, salt, 10, 16, 'sha512', (err, key) => {
      if (err) {
        console.log(err); 
      } else {
        key = key.toString('hex');
        const cipher = crypto.createCipheriv('aes-256-gcm', key, salt);
        let encrypted = cipher.update(text, 'utf8', 'hex') + cipher.final('hex'); // Fix 1a: call final(): create tag
        let tag = cipher.getAuthTag(); // Fix 2a: get tag 
        console.log(encrypted + tag.toString('hex')); // Fix 3a: concat ciphertext and tag 
      }
    });
  },
  decrypt(text, password, salt) {
    var tag = Buffer.from(text.substr(-32, 32), 'hex'); // Fix 3b: Separate ciphertext and tag
    var ciphertext = text.substr(0, text.length - 32);
    password = password.repeat(32).substr(0, 32);
    salt = salt.repeat(16).substr(0, 16);
    crypto.pbkdf2(password, salt, 10, 16, 'sha512', (err, key) => {
      if (err) {
        console.log(err); 
      } else {
        key = key.toString('hex');
        const cipher = crypto.createDecipheriv('aes-256-gcm', key, salt);
        cipher.setAuthTag(tag); // Fix 2b: set  tag
        try {
          let decrypted = cipher.update(ciphertext, 'hex', 'utf8') + cipher.final('utf8'); // Fix 1b: call final(): authenticate
          console.log(decrypted);
        } catch (e) {
          console.log("Authentication failed!");
        }
      }
    });
  }
}

const message = 'Hello World';
app.encrypt(message, 'password', 'salt');

const cipherText = 'a0a4e0ad971334948565023568ae285d45b9cefc80abe3afcf9155';
app.decrypt(cipherText, 'password', 'salt');
app.decrypt(cipherText, 'password123', 'salt');
about 4 years ago · Santiago Gelvez Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda