question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Decrypting appends invalid characters to message

See original GitHub issue

Hey, I try to encrypt and decrypt JSON using the simple secretbox method, here is what I got:

import { secretbox, randomBytes } from 'tweetnacl';
import { decodeUTF8, encodeUTF8, encodeBase64, decodeBase64 } from 'tweetnacl-util';

const newNonce = () => randomBytes(secretbox.nonceLength);

export const generateKey = () => encodeBase64(randomBytes(secretbox.keyLength));

export const encrypt = (json, password) => {
  const passwordUint8Array = decodeBase64(password);

  const nonce = newNonce();
  const messageUint8 = decodeUTF8(JSON.stringify(json));
  const box = secretbox(messageUint8, nonce, passwordUint8Array);

  const fullMessage = new Uint8Array(nonce.length + box.length);
  fullMessage.set(nonce);
  fullMessage.set(messageUint8, nonce.length);

  const base64FullMessage = encodeBase64(fullMessage);
  return base64FullMessage;
};

export const decrypt = (messageWithNonce, password) => {
  const passwordUint8Array = decodeBase64(password);
  const messageWithNonceAsUint8Array = decodeBase64(messageWithNonce);
  const nonce = messageWithNonceAsUint8Array.slice(0, secretbox.nonceLength);
  const message = messageWithNonceAsUint8Array.slice(
    secretbox.nonceLength,
    messageWithNonce.length,
  );

  const box = secretbox(message, nonce, passwordUint8Array);
  const decrypted = secretbox.open(box, nonce, passwordUint8Array);

  const base64DecryptedMessage = encodeUTF8(decrypted);
  return JSON.parse(base64DecryptedMessage.substr(0, base64DecryptedMessage.lastIndexOf('}') + 1));
};

As you can see at the very bottom, I’m creating a substr of the decrypted message, since at the end, there is always some invisible, invalid characters. Any idea of why?

Does the rest seem alright? Maybe it would be a good usage example.

Thanks!

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:10 (9 by maintainers)

github_iconTop GitHub Comments

2reactions
bknifflercommented, Sep 13, 2017

Wow, that was stupid, thanks @dchest!

Here the full working example for anyone stumbling over this:

import { secretbox, randomBytes } from "tweetnacl";
import {
  decodeUTF8,
  encodeUTF8,
  encodeBase64,
  decodeBase64
} from "tweetnacl-util";

const newNonce = () => randomBytes(secretbox.nonceLength);

export const generateKey = () => encodeBase64(randomBytes(secretbox.keyLength));

export const encrypt = (json, key) => {
  const keyUint8Array = decodeBase64(key);

  const nonce = newNonce();
  const messageUint8 = decodeUTF8(JSON.stringify(json));
  const box = secretbox(messageUint8, nonce, keyUint8Array);

  const fullMessage = new Uint8Array(nonce.length + box.length);
  fullMessage.set(nonce);
  fullMessage.set(box, nonce.length);

  const base64FullMessage = encodeBase64(fullMessage);
  return base64FullMessage;
};

export const decrypt = (messageWithNonce, key) => {
  const keyUint8Array = decodeBase64(key);
  const messageWithNonceAsUint8Array = decodeBase64(messageWithNonce);
  const nonce = messageWithNonceAsUint8Array.slice(0, secretbox.nonceLength);
  const message = messageWithNonceAsUint8Array.slice(
    secretbox.nonceLength,
    messageWithNonce.length
  );

  const decrypted = secretbox.open(message, nonce, keyUint8Array);

  if (!decrypted) {
    throw new Error("Could not decrypt message");
  }

  const base64DecryptedMessage = encodeUTF8(decrypted);
  return JSON.parse(base64DecryptedMessage);
};

0reactions
bknifflercommented, Sep 14, 2017

@NullVoxPopuli Not exactly, while decrypting you are doing

  const box = NaCl.box(message, nonce, theirPublicKeyUint8Array, mySecretKeyUint8Array);
  const decrypted = NaCl.box.open(box, nonce, theirPublicKeyUint8Array, mySecretKeyUint8Array);

which @dchest hinted me isn’t good since you encrypt the message again

  const decrypted = secretbox.open(message, nonce, keyUint8Array);

Please note my code is about secretbox, not box, but I think its still analogue.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Invalid character in a Base-64 string when attempting decryption ...
When I attempt to read in encrypted text from a text file and then decrypt it I get the following error. Invalid character...
Read more >
html_entity_decode - Manual - PHP
More precisely, this function decodes all the entities (including all numeric entities) that a) are necessarily valid for the chosen document type —...
Read more >
Find k'th character of decrypted string | Set 1 - GeeksforGeeks
The idea is simple, Initially take empty decrypted string. decompress the string by reading substring and it's frequency one by one and append...
Read more >
Encryption and Decryption in Python - Nitratine
In this post, I discuss how to encrypt and decrypt messages in Python using symmetric encryption. I will demonstrate how to create keys, ......
Read more >
CA1268258A - Method and apparatus for synchronizing encrypting ...
Thus, the key becomes another input, or argument, to the encoding algorithm along with the plain text message characters. In such systems, a...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found