1

I read a post: encrypted-data-between-node-js-and-python.

I need to implement the reverse path, create the encryption in python and decode in the node.

On the Python side I did:

from nacl.secret import SecretBox
from base64 import b64encode
import nacl.secret
import nacl.utils

secret_key = bytes('_THIS_IS_MY_32_CHARS_SECRET_KEY_', 'utf8')
message =  bytes('Some Italians hate wine','utf-8')

nonce = nacl.utils.random(24)

box = SecretBox(secret_key)
encrypted = box.encrypt(message,nonce)
ctext = encrypted.ciphertext
print(ctext)

plaintext = box.decrypt(encrypted)
print(plaintext.decode('utf-8'))

print(b64encode(nonce))
print(b64encode(encrypted

In node:

const nacl = require('tweetnacl');
const utils = require('tweetnacl-util');
const secretKey = Buffer.from('_THIS_IS_MY_32_CHARS_SECRET_KEY_', 'utf8');
const nonce = utils.decodeBase64('KRmiqOFUN1HklmPZgbd0BINNDDCu3dyB');
      
const encryptedMessage = utils.decodeBase64('KRmiqOFUN1HklmPZgbd0BINNDDCu3dyB/s4tdTjcw65K6Lr5N797+7zoLm9WClCXIDNLAqrNGwF2MybtJu+U');
    
const originalMessage = nacl.secretbox.open(
    encryptedMessage,
    nonce,
    secretKey
);

The result was NULL.

What is the correct way to do this integration?

Topaco
  • 40,594
  • 4
  • 35
  • 62
Israel Zebulon
  • 262
  • 3
  • 12

1 Answers1

3

encrypted returned by SecretBox.encrypt() in the PyNaCl code is an EncryptedMessage object (a bytes subclass) that holds the concatenated (24 bytes) nonce and ciphertext. Note that EncryptedMessage also has the properties nonce and ciphertext.

Since the TweetNaCl code uses the concatenated (Base64 encoded) data, these data must first be separated (after Base64 decoding) and nonce and ciphertext must be processed separately in nacl.secretbox.open(). Please note that TweetNaCl uses TypedArrays. For the conversion to or from Utf8 or Base64 the functions from tweetnacl-util can be used:

const secretKey = nacl.util.decodeUTF8('_THIS_IS_MY_32_CHARS_SECRET_KEY_');
const encryptedMessage = nacl.util.decodeBase64('KRmiqOFUN1HklmPZgbd0BINNDDCu3dyB/s4tdTjcw65K6Lr5N797+7zoLm9WClCXIDNLAqrNGwF2MybtJu+U');

// Separate nonce and ciphertext
const nonce = encryptedMessage.slice(0, 24)
const ciphertext = encryptedMessage.slice(24) 

// Decrypt
const originalMessage = nacl.secretbox.open(ciphertext, nonce, secretKey);

const decryptedText = nacl.util.encodeUTF8(originalMessage);
console.log(decryptedText); // Some Italians hate wine    
<script src="https://cdn.jsdelivr.net/npm/tweetnacl-util@0.15.1/nacl-util.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/tweetnacl@1.0.3/nacl.min.js"></script>

Please note that this snippet is pure JavaScript. In your NodeJS environment you have to replace nacl.util with utils.

Topaco
  • 40,594
  • 4
  • 35
  • 62
  • Excellent code and explanation. I'm looking how to go the other direction (encryption in JS and decryption in python): will let you know what I find! – WestCoastProjects Sep 15 '21 at 13:25