Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aesCbc.decrypt not suport emoji #76

Closed
easychen opened this issue Oct 28, 2018 · 9 comments
Closed

aesCbc.decrypt not suport emoji #76

easychen opened this issue Oct 28, 2018 · 9 comments

Comments

@easychen
Copy link

I found aes-js's aesCbc.decrypt can't decrypt string with emoji , such as 🍩 🙃 .

details :

first , I use php encrypt a string ,and then decrypt it

$key = "b0baee9d279d34fa";
$iv = "e11170b8cbd2d741" ;

$out = openssl_encrypt( "emoji 🙃 " , 'AES-128-CBC' ,  $key , 0 , $iv  );
echo $out ."\r\n";
echo openssl_decrypt( $out , 'AES-128-CBC' ,  $key , 0 , $iv  );

output:

CUTfIyfmlek9G9lfYwAe8g==
emoji 🙃 

It works fine which means the encrypted stirng is right.

then , when I decrypt it with aes-js , 🙃 destoried .

const key = aesjs.utils.utf8.toBytes( "b0baee9d279d34fa" );
const iv = aesjs.utils.utf8.toBytes( "e11170b8cbd2d741");

var buf = Buffer.from( "CUTfIyfmlek9G9lfYwAe8g==" , 'base64');
var aesCbc = new aesjs.ModeOfOperation.cbc(key, iv);

let decryptedBytes = aesCbc.decrypt(buf);                
let decryptedText = aesjs.utils.utf8.fromBytes(decryptedBytes);
console.log( decryptedText );

output:

emoji ߙ㠅����
@hdwang123
Copy link

I also have the same problem whith decript the emoji string. how can I fix it.

@easychen
Copy link
Author

I also have the same problem whith decript the emoji string. how can I fix it.

use base64 to wrap it for now…

@hdwang123
Copy link

I had solve the problem. relace the method 【convertUtf8】 in the index.js

  /**
  • utf8 byte to unicode string

  • @param utf8Bytes

  • @returns {string}
    */
    function utf8ByteToUnicodeStr(utf8Bytes){
    var unicodeStr ="";
    for (var pos = 0; pos < utf8Bytes.length;){
    var flag= utf8Bytes[pos];
    var unicode = 0 ;
    if ((flag >>>7) === 0 ) {
    unicodeStr+= String.fromCharCode(utf8Bytes[pos]);
    pos += 1;

     } else if ((flag &0xFC) === 0xFC ){
         unicode = (utf8Bytes[pos] & 0x3) << 30;
         unicode |= (utf8Bytes[pos+1] & 0x3F) << 24;
         unicode |= (utf8Bytes[pos+2] & 0x3F) << 18;
         unicode |= (utf8Bytes[pos+3] & 0x3F) << 12;
         unicode |= (utf8Bytes[pos+4] & 0x3F) << 6;
         unicode |= (utf8Bytes[pos+5] & 0x3F);
         unicodeStr+= String.fromCodePoint(unicode) ;
         pos += 6;
    
     }else if ((flag &0xF8) === 0xF8 ){
         unicode = (utf8Bytes[pos] & 0x7) << 24;
         unicode |= (utf8Bytes[pos+1] & 0x3F) << 18;
         unicode |= (utf8Bytes[pos+2] & 0x3F) << 12;
         unicode |= (utf8Bytes[pos+3] & 0x3F) << 6;
         unicode |= (utf8Bytes[pos+4] & 0x3F);
         unicodeStr+= String.fromCodePoint(unicode) ;
         pos += 5;
    
     } else if ((flag &0xF0) === 0xF0 ){
         unicode = (utf8Bytes[pos] & 0xF) << 18;
         unicode |= (utf8Bytes[pos+1] & 0x3F) << 12;
         unicode |= (utf8Bytes[pos+2] & 0x3F) << 6;
         unicode |= (utf8Bytes[pos+3] & 0x3F);
         unicodeStr+= String.fromCodePoint(unicode) ;
         pos += 4;
    
     } else if ((flag &0xE0) === 0xE0 ){
         unicode = (utf8Bytes[pos] & 0x1F) << 12;;
         unicode |= (utf8Bytes[pos+1] & 0x3F) << 6;
         unicode |= (utf8Bytes[pos+2] & 0x3F);
         unicodeStr+= String.fromCharCode(unicode) ;
         pos += 3;
    
     } else if ((flag &0xC0) === 0xC0 ){ //110
         unicode = (utf8Bytes[pos] & 0x3F) << 6;
         unicode |= (utf8Bytes[pos+1] & 0x3F);
         unicodeStr+= String.fromCharCode(unicode) ;
         pos += 2;
    
     } else{
         unicodeStr+= String.fromCharCode(utf8Bytes[pos]);
         pos += 1;
     }
    

    }
    return unicodeStr;
    }

     return {
         toBytes: toBytes,
         fromBytes: utf8ByteToUnicodeStr,
     }
    

@Ruffio
Copy link

Ruffio commented Jan 31, 2019

Should this fix be implemented?

@ricmoo
Copy link
Owner

ricmoo commented Feb 11, 2019

I plan to remove the UTF-8 libraries entirely from aes-js in the next version as there are many, much more complete implementations, and it has been a source of confusion for many people using UTF-8 strings not realizing they are viable as a binary encoding.

For a more complete implementation, please see my ethers.js library:

There are a lot of additional edge cases these libraries handle, which are essential for security focused applications. The UTF-8 coding by themselves is as large as the entire AES cipher. :)

@vadhack
Copy link

vadhack commented Jun 14, 2019

I also have the same problem whith decript the emoji string. how can I fix it.

use base64 to wrap it for now…

How can i do that? can you explain?

@vadhack
Copy link

vadhack commented Jun 14, 2019

i can't find any solution, the emojis destroy my json string

@jimmylee
Copy link

I used @hdwang123's solution above and it worked for me as a replacement for AES.utils.utf8.fromBytes

@SashaSirotkin
Copy link

You can also just use the built-in TextEncoder API.

new TextEncoder('utf-8').encode(text);
new TextDecoder('utf-8').decode(bytes);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants