5

using nodejs I am trying to generate an unique URL for user to conform email address. From that URL user will be able to verify the email account by decrypting the ciphertext and comparing ciphertext data with database . I am using CryptoJS to generate the url.

let url = 'http://localhost:4000/newUser/get/'+ciphertext ;

Problem is that in ciphertext, it contains forward slash " / " eg:

http://localhost:4000/newUser/get/U2FsdGVkX189ZNKKQrYgqU90DDwkl/W3hRTSGO1yvUMaDilPJmz9YYI3d1/E3i9C

Router is processing " / " on the URL, thus router is searching for the directory that is actually part of ciphertext. If there is any solution for not including " / " or special characters in ciphertext, please help. Thanks in advance.

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
Shashank
  • 397
  • 2
  • 7
  • 17
  • please provide node.js code you're using to generate ciphertext – Miguel Mota Apr 13 '17 at 18:17
  • 1
    `ciphertext.replace(/\//g,"-")`? (And then change `-` back to `/` on the server before comparing it to the database) – apsillers Apr 13 '17 at 18:30
  • If this is a token, then you **must not** use some kind of ciphertext. Just generate a random token, store it in your database and encode it with URL-safe Base64 encoding. When the user clicks it, you decode the token and query the database to see if there is such a token. – Artjom B. Apr 13 '17 at 18:40
  • Possible duplicate of [Websafe encoding of hashed string in nodejs](http://stackoverflow.com/questions/17639645/websafe-encoding-of-hashed-string-in-nodejs) – Artjom B. Apr 13 '17 at 18:44
  • 2
    Use URL encode will solve your problem, refer to this post http://stackoverflow.com/questions/2992231/slashes-in-url-variables – thelonglqd Apr 13 '17 at 18:52
  • 1
    thanks @apsillers `.replace()` works well. while decrypt, I've used `ciphertext = ciphertext.replace(/\+/g, 'aFaFa').replace(/\//g, 'bFbFb').replace(/=+$/, 'cFcFc');` while encrypt, I've use `ciphertext = ciphertext.replace('aFaFa', '+' ).replace('bFbFb', '/').replace('cFcFc', '=');` – Shashank Apr 14 '17 at 15:01

6 Answers6

9

You can easily replace the special characters with any of text like:

ciphertext.toString().replace('+','xMl3Jk').replace('/','Por21Ld').replace('=','Ml32');

Do not forget to replace these strings back with special characters

dataString.toString().replace('xMl3Jk', '+' ).replace('Por21Ld', '/').replace('Ml32', '=');

Hope this will help to solve your problem

Jai Chauhan
  • 4,035
  • 3
  • 36
  • 62
4

However, .replace() will only replace first occurrence.

To be more precise, you can use something like this :

// Original Text
var ciphertext = 'asda+dasd+asdas/asdasd/sadasdasd/dadasd=adsasda=dasd=';

// Replaced Text
var dataString = ciphertext.replace(/\+/g,'p1L2u3S').replace(/\//g,'s1L2a3S4h').replace(/=/g,'e1Q2u3A4l');
console.log(dataString);

// Back to Original Text
ciphertext = dataString.replace(/p1L2u3S/g, '+' ).replace(/s1L2a3S4h/g, '/').replace(/e1Q2u3A4l/g, '=');
console.log(ciphertext);
Darshan Gada
  • 583
  • 5
  • 9
3

IMHO, for @JaiKumarRajput's answer,

He encoded the string with,

ciphertext.toString().replace('+','xMl3Jk').replace('/','Por21Ld').replace('=','Ml32');

Now, I have no idea how xMl3Jk, Por21Ld, Ml32 works. So, i also don't know if it can mess my string somehow.
Plus, As I have to perform this on decoding as well. So, Why wont I use something like this (What already exists),

encodeURIComponent(ciphertext.toString('base64'))

I know it still introduces % char. But as its getting used in URL. In which its a escape char.

How does it matter more than doing something that can mess my code up ??

NOTE: I used it and had no issue, It doesn't mean I either had found any issue with the top one. That didn't feel neat. Its only my humble opinion, So if u don't like it? Ignore it.

2

I have got the same problem, this works out for me:

const aesKey = CryptoJS.enc.Utf8.parse('aeskeyaeskeyaeskeyaeskeyaeskey32');
const aesIv = CryptoJS.enc.Utf8.parse('0123456789abcdef');
const aesOptions = {
  iv: aesIv,
  mode: CryptoJS.mode.CBC,
  padding: CryptoJS.pad.Pkcs7,
};

const plaintext = 'iamtheoriginal';
const ciphertext = CryptoJS.AES.encrypt(plaintext, aesKey, aesOptions).ciphertext.toString(); // 'c3a48990119bdfe40b6c32ec2aca8b93'

const encoded = {ciphertext: CryptoJS.enc.Hex.parse(ciphertext)};
const decodedText = CryptoJS.enc.Utf8.stringify(CryptoJS.AES.decrypt(encoded, aesKey, aesOptions)); // 'iamtheoriginal'

The ciphertext is 'c3a48990119bdfe40b6c32ec2aca8b93', has no special chars, and can be decrypted back to the original text, and it can encrypt all utf8 words like Chinese and even emoji.

0

There is no option for excluding / while crypto generate a encryped string.

I had face the same issue and then i found urlencode

const urlencode = require('urlencode');
 
let xx = {
    chatRoomId: 37,
    userId: 1,
    doctorId: 2
}

xx = JSON.stringify(xx)
//encode 
let x = (urlencode(xx, 'gbk')); // '%CB%D5%C7%A7'

// decode gbk
let y = urlencode.decode(x, 'gbk'); // original plain text
console.log(y)
Tanjin Alam
  • 1,728
  • 13
  • 15
0

// Original Text 
let ciphertext = 'asda+dasd+asdas/asdasd/sadasdasd/dadasd=adsasda=dasd=';
let encodeText = encodeURIComponent(ciphertext);
console.log(encodeText)

let decodeText = decodeURIComponent(encodeText);
console.log(decodeText)

you can use like this. first encode your ciphertext like above and concatenate that encodeText with ulr

let url = 'http://localhost:4000/newUser/get/'+encodeText ;

and then decode that encodeText from ulr

Bilal
  • 95
  • 1
  • 1
  • 10