From 147e0d6389c3cade135e44af98fc785f03004d72 Mon Sep 17 00:00:00 2001 From: ding_chengjie Date: Thu, 24 Nov 2022 15:11:56 +0800 Subject: [PATCH 1/2] Fix the encryption errors of special characters and Chinese characters in the encryption algorithm Signed-off-by: ding_chengjie --- CHANGELOG.md | 4 ++ crypto/package.json | 2 +- crypto/src/main/ets/crypto.ts | 73 ++++++++++++++++++++++++++++++++++- 3 files changed, 76 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53c9716..8f3be31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## v1.0.3 + +1. 修复加密算法中特殊字符以及中文字符加密错误的问题 + ## v1.0.2 1. 适配API9 diff --git a/crypto/package.json b/crypto/package.json index 1822271..7142d79 100644 --- a/crypto/package.json +++ b/crypto/package.json @@ -11,7 +11,7 @@ }, "main": "index.ets", "repository": "https://gitee.com/openharmony-sig/crypto-js", - "version": "1.0.2", + "version": "1.0.3", "tags": [ "crypto-js", "OpenHarmony" diff --git a/crypto/src/main/ets/crypto.ts b/crypto/src/main/ets/crypto.ts index d964133..c299d94 100644 --- a/crypto/src/main/ets/crypto.ts +++ b/crypto/src/main/ets/crypto.ts @@ -13,6 +13,7 @@ * limitations under the License. */ +import buffer from '@ohos.buffer'; import CryptoJS from 'crypto-js'; export { CryptoJS } @@ -51,6 +52,74 @@ CryptoJS.enc.Utf8.stringify = function (wordArray) { } } -CryptoJS.enc.Utf8.parse = function (utf8Str) { - return CryptoJS.enc.Latin1.parse(encodeURI(utf8Str)); +const unhexTable = new Int8Array([ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0 - 15 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16 - 31 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 32 - 47 + +0, +1, +2, +3, +4, +5, +6, +7, +8, +9, -1, -1, -1, -1, -1, -1, // 48 - 63 + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 64 - 79 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 80 - 95 + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 96 - 111 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 112 - 127 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 128 ... + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 255 +]); +/** + * A safe fast alternative to decodeURIComponent + * @param {string} s + * @param {boolean} decodeSpaces + * @returns {string} + */ +function unescapeBuffer(s, decodeSpaces) { + const out = buffer.alloc(s.length); + let index = 0; + let outIndex = 0; + let currentChar; + let nextChar; + let hexHigh; + let hexLow; + const maxLength = s.length - 2; + // Flag to know if some hex chars have been decoded + let hasHex = false; + while (index < s.length) { + currentChar = s.charCodeAt(index) + if (currentChar === 43 /* '+' */ + && decodeSpaces) { + out[outIndex++] = 32; // ' ' + index++; + continue; + } + if (currentChar === 37 /* '%' */ + && index < maxLength) { + currentChar = s.charCodeAt(++index); + hexHigh = unhexTable[currentChar]; + if (!(hexHigh >= 0)) { + out[outIndex++] = 37; // '%' + continue; + } else { + nextChar = s.charCodeAt(++index); + hexLow = unhexTable[nextChar]; + if (!(hexLow >= 0)) { + out[outIndex++] = 37; // '%' + index--; + } else { + hasHex = true; + currentChar = hexHigh * 16 + hexLow; + } + } + } + out[outIndex++] = currentChar; + index++; + } + return hasHex ? out.subarray(0, outIndex) : out; } + +CryptoJS.enc.Utf8.parse = function (utf8Str) { + return CryptoJS.enc.Latin1.parse(unescapeBuffer(encodeURIComponent(utf8Str), false).toString("binary")); +} \ No newline at end of file -- Gitee From 757f750b6e0c2bcd00041b08d8cbfdafc057d013 Mon Sep 17 00:00:00 2001 From: ding_chengjie Date: Thu, 1 Dec 2022 17:59:02 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E5=8A=A0=E8=A7=A3?= =?UTF-8?q?=E5=AF=86=E4=B8=8D=E5=8F=AF=E9=80=86=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ding_chengjie --- crypto/package.json | 1 + crypto/src/main/ets/UnescapeBuffer.ts | 87 +++++++++++++++++++++++++++ crypto/src/main/ets/crypto.ts | 75 ++--------------------- 3 files changed, 92 insertions(+), 71 deletions(-) create mode 100644 crypto/src/main/ets/UnescapeBuffer.ts diff --git a/crypto/package.json b/crypto/package.json index 7142d79..51936f0 100644 --- a/crypto/package.json +++ b/crypto/package.json @@ -17,6 +17,7 @@ "OpenHarmony" ], "dependencies": { + "@ohos/openharmony-node-polyfill": "^0.1.0", "crypto-js": "^4.1.1" }, "license": "MIT", diff --git a/crypto/src/main/ets/UnescapeBuffer.ts b/crypto/src/main/ets/UnescapeBuffer.ts new file mode 100644 index 0000000..5640df5 --- /dev/null +++ b/crypto/src/main/ets/UnescapeBuffer.ts @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the MIT License, (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://opensource.org/licenses/MIT + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import buffer from '@ohos.buffer'; + +const unhexTable = new Int8Array([ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0 - 15 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16 - 31 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 32 - 47 + +0, +1, +2, +3, +4, +5, +6, +7, +8, +9, -1, -1, -1, -1, -1, -1, // 48 - 63 + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 64 - 79 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 80 - 95 + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 96 - 111 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 112 - 127 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 128 ... + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 255 +]); + +export default class UnescapeBuffer { + /** + * A safe fast alternative to decodeURIComponent + * @param {string} s + * @param {boolean} decodeSpaces + * @returns {string} + */ + unescapeBuffer(s, decodeSpaces) { + const out = buffer.alloc(s.length); + let index = 0; + let outIndex = 0; + let currentChar; + let nextChar; + let hexHigh; + let hexLow; + const maxLength = s.length - 2; + // Flag to know if some hex chars have been decoded + let hasHex = false; + while (index < s.length) { + currentChar = s.charCodeAt(index) + if (currentChar === 43 /* '+' */ + && decodeSpaces) { + out[outIndex++] = 32; // ' ' + index++; + continue; + } + if (currentChar === 37 /* '%' */ + && index < maxLength) { + currentChar = s.charCodeAt(++index); + hexHigh = unhexTable[currentChar]; + if (!(hexHigh >= 0)) { + out[outIndex++] = 37; // '%' + continue; + } else { + nextChar = s.charCodeAt(++index); + hexLow = unhexTable[nextChar]; + if (!(hexLow >= 0)) { + out[outIndex++] = 37; // '%' + index--; + } else { + hasHex = true; + currentChar = hexHigh * 16 + hexLow; + } + } + } + out[outIndex++] = currentChar; + index++; + } + return hasHex ? out.subarray(0, outIndex) : out; + } +} diff --git a/crypto/src/main/ets/crypto.ts b/crypto/src/main/ets/crypto.ts index c299d94..a45d839 100644 --- a/crypto/src/main/ets/crypto.ts +++ b/crypto/src/main/ets/crypto.ts @@ -13,8 +13,9 @@ * limitations under the License. */ -import buffer from '@ohos.buffer'; import CryptoJS from 'crypto-js'; +import OpenHarmonyBuffer from "@ohos/openharmony-node-polyfill/lib/node/buffer" +import UnescapeBuffer from "./UnescapeBuffer" export { CryptoJS } @@ -46,80 +47,12 @@ CryptoJS.lib.WordArray.random = function (nBytes) { CryptoJS.enc.Utf8.stringify = function (wordArray) { try { - return decodeURI(CryptoJS.enc.Latin1.stringify(wordArray)); + return OpenHarmonyBuffer.Buffer.from(CryptoJS.enc.Latin1.stringify(wordArray), "Latin1").toString("utf-8"); } catch (e) { throw new Error('Malformed UTF-8 data'); } } -const unhexTable = new Int8Array([ - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0 - 15 - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16 - 31 - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 32 - 47 - +0, +1, +2, +3, +4, +5, +6, +7, +8, +9, -1, -1, -1, -1, -1, -1, // 48 - 63 - -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 64 - 79 - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 80 - 95 - -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 96 - 111 - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 112 - 127 - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 128 ... - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 255 -]); -/** - * A safe fast alternative to decodeURIComponent - * @param {string} s - * @param {boolean} decodeSpaces - * @returns {string} - */ -function unescapeBuffer(s, decodeSpaces) { - const out = buffer.alloc(s.length); - let index = 0; - let outIndex = 0; - let currentChar; - let nextChar; - let hexHigh; - let hexLow; - const maxLength = s.length - 2; - // Flag to know if some hex chars have been decoded - let hasHex = false; - while (index < s.length) { - currentChar = s.charCodeAt(index) - if (currentChar === 43 /* '+' */ - && decodeSpaces) { - out[outIndex++] = 32; // ' ' - index++; - continue; - } - if (currentChar === 37 /* '%' */ - && index < maxLength) { - currentChar = s.charCodeAt(++index); - hexHigh = unhexTable[currentChar]; - if (!(hexHigh >= 0)) { - out[outIndex++] = 37; // '%' - continue; - } else { - nextChar = s.charCodeAt(++index); - hexLow = unhexTable[nextChar]; - if (!(hexLow >= 0)) { - out[outIndex++] = 37; // '%' - index--; - } else { - hasHex = true; - currentChar = hexHigh * 16 + hexLow; - } - } - } - out[outIndex++] = currentChar; - index++; - } - return hasHex ? out.subarray(0, outIndex) : out; -} - CryptoJS.enc.Utf8.parse = function (utf8Str) { - return CryptoJS.enc.Latin1.parse(unescapeBuffer(encodeURIComponent(utf8Str), false).toString("binary")); + return CryptoJS.enc.Latin1.parse(UnescapeBuffer.prototype.unescapeBuffer(encodeURIComponent(utf8Str), false).toString("binary")); } \ No newline at end of file -- Gitee