yisbug / whatsapp-nodejs

This is a library based on whatsapp androd latest version, you can use it build your own app.
36 stars 12 forks source link

BAD MAC Exception from whatsapp business #11

Open aarctb opened 1 year ago

aarctb commented 1 year ago

@yisbug do you know something about this error?

Received message from whatsapp fine works Received message from whatsapp business throw bellow exception:

Nov 30 00:27:35 WA[12768] ERROR: Bad MAC err: Error: Bad MAC at Object. (/root/whatsapp/whatsapp-nodejs/node_modules/@privacyresearch/libsignal-protocol-typescript/lib/internal/crypto.js:154:19) at Generator.next () at fulfilled (/root/whatsapp/whatsapp-nodejs/node_modules/@privacyresearch/libsignal-protocol-typescript/lib/internal/crypto.js:24:58)

yisbug commented 1 year ago

@yisbug do you know something about this error?

Received message from whatsapp fine works Received message from whatsapp business throw bellow exception:

Nov 30 00:27:35 WA[12768] ERROR: Bad MAC err: Error: Bad MAC at Object. (/root/whatsapp/whatsapp-nodejs/node_modules/@privacyresearch/libsignal-protocol-typescript/lib/internal/crypto.js:154:19) at Generator.next () at fulfilled (/root/whatsapp/whatsapp-nodejs/node_modules/@privacyresearch/libsignal-protocol-typescript/lib/internal/crypto.js:24:58)

This is a message verification failure, which can be ignored. You can modify node_ modules. Ignore this error.

aarctb commented 1 year ago

@yisbug messages received from whatsapp business whith the encType equal pkmsg the lib throw exception BAD MAC at the bellow line:

"const res = await this.signal.decrypt_pkmsg(senderJid, encNode.data, true)"

in whatsapp.js file and the message is not decrypted.

whatsapp.js 

  async handlePreKeyWhisperMessage(senderJid, encNode, node) {
    console.debug('handlePreKeyWhisperMessage', senderJid);
    const res = await this.signal.decrypt_pkmsg(senderJid, encNode.data, true);  // ==> EXCEPTION IN THIS LINE
   const buffer = Message.decode(Buffer.from(res)).toJSON();
    await this.checkAndCreateGroupSession(buffer, node);
    return buffer;
  }

if I comment the IF instruction in node_modules/@privacyresearch/libsignal-protocol-typescript/lib/internal/crypto.js:154:19 the lib throw another exception and the message is not decrypted.

message is empty
  err: Error: message is empty
      at Whatsapp.onMessageContact (/root/whatsapp/whatsapp-nodejs/src/Whatsapp.js:606:15)

At least for me, I am not able to receive messages from whatsapp business.

yisbug commented 1 year ago

@yisbug messages received from whatsapp business whith the encType equal pkmsg the lib throw exception BAD MAC at the bellow line:

"const res = await this.signal.decrypt_pkmsg(senderJid, encNode.data, true)"

in whatsapp.js file and the message is not decrypted.

whatsapp.js 

  async handlePreKeyWhisperMessage(senderJid, encNode, node) {
    console.debug('handlePreKeyWhisperMessage', senderJid);
    const res = await this.signal.decrypt_pkmsg(senderJid, encNode.data, true);  // ==> EXCEPTION IN THIS LINE
   const buffer = Message.decode(Buffer.from(res)).toJSON();
    await this.checkAndCreateGroupSession(buffer, node);
    return buffer;
  }

if I comment the IF instruction in node_modules/@privacyresearch/libsignal-protocol-typescript/lib/internal/crypto.js:154:19 the lib throw another exception and the message is not decrypted.

message is empty
  err: Error: message is empty
      at Whatsapp.onMessageContact (/root/whatsapp/whatsapp-nodejs/src/Whatsapp.js:606:15)

At least for me, I am not able to receive messages from whatsapp business.

If the message is empty, the retry logic will generally be triggered. The retry code is as follows:


      const encNode = node.getChild('enc');
      const count = Number(encNode.getAttr('count')) || 0;

      if (count > 3) return; // max retry count 3
      if (count === 0) {
        // send retry pack
        this.sendReceipt(
          {
            to: utils.normalize(jid),
            type: 'retry',
            id,
          },
          [
            new ProtocolEntity('retry', {
              t: node.getAttr('t'),
              id,
              count: '1',
              v: '1',
            }).toProtocolTreeNode(),
            new ProtocolEntity(
              'registration',
              null,
              null,
              this.adjustId(this.signal.registrationId, 8)
            ).toProtocolTreeNode(),
          ]
        );
      } else {
        const retryNode = new RetryKeysProtocolEntity(
          {
            to: utils.normalize(jid),
            type: 'retry',
            id,
          },
          {
            t: node.getAttr('t'),
            id,
            count: String(count + 1),
            v: '1',
          },
          this.signal.identityKeyPair.pubKey,
          this.signal.signedPrekey,
          this.signal.preKeys[0].preKey,
          5,
          this.signal.registrationId
        ).toProtocolTreeNode();
        this.sendNode(retryNode);
      }