Skip to content

Conversation

@wojiaoyishang
Copy link

Overview

When using CryptoJS to encode non-ASCII characters, the resulting encrypted output cannot be decrypted properly.

import js2py

CryptoJS = js2py.require('crypto-js')
print(CryptoJS.AES.encrypt("你好世界!", "test").toString())

image

Problem

During the encryption process, CryptoJS utilizes the deprecated unescape function.

image

Investigation revealed that the escape and unescape functions in the Python environment operate inconsistently with those in the JavaScript environment.

image

According to the documentation, unescape() should not be used for decoding URIs. The unescape() function replaces any escape sequences with the characters they represent. Specifically, it replaces any escape sequences in the form of %XX or %uXXXX (where X represents a hexadecimal digit) with the character having the hexadecimal value XX/XXXX. If the escape sequence is not a valid one (for example, if % is followed by one or no hexadecimal digits), it is left unchanged.

fix

A new implementation method for the escape and unescape functions has been provided.

@Js
def escape(text):
    def replacer(match):
        char = match.group()
        code = ord(char)
        if code <= 0xff:
            return f'%{code:02X}'
        else:
            return f'%u{code:04X}'
    return re.sub(r'[^A-Za-z0-9@*_+\-./]', replacer, text.to_python())


@Js
def unescape(text):
    def replacer(match):
        u_group = match.group(1)
        hex_group = match.group(2)
        if u_group is not None:
            return chr(int(u_group, 16))
        elif hex_group is not None:
            return chr(int(hex_group, 16))
        return match.group()
    return re.sub(r'%u([0-9A-Fa-f]{4})|%([0-9A-Fa-f]{2})', replacer, text.to_python(), flags=re.IGNORECASE)

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

Successfully merging this pull request may close these issues.

1 participant