diff --git a/imgdec.js b/imgdec.js index bb05c91..0871621 100644 --- a/imgdec.js +++ b/imgdec.js @@ -1,4 +1,275 @@ +(function() { + //by LoyDgIk + const jvString = java.lang.String; + const jvArray = java.lang.reflect.Array; + const Byte = java.lang.Byte; + const Integer = java.lang.Integer; + + const StandardCharsets = java.nio.charset.StandardCharsets; + const MessageDigest = java.security.MessageDigest; + const Base64 = android.util.Base64; + const StringBuffer = java.lang.StringBuffer; + + const Cipher = javax.crypto.Cipher; + const IvParameterSpec = javax.crypto.spec.IvParameterSpec; + const SecretKeySpec = javax.crypto.spec.SecretKeySpec; + const FileUtil = com.example.hikerview.utils.FileUtil; + + //CryptoUtil + //互转类 + function Data(bytes) { + this.bytes = bytes; + this.length = bytes.length; + } + + Object.assign(Data, { + parseStr(str, charset) { + return new Data(toJvString(str).getBytes(charset)); + }, + parseUTF8(str) { + return Data.parseStr(str, StandardCharsets.UTF_8); + }, + parseUTF16(str) { + return Data.parseStr(str, StandardCharsets.UTF_16); + }, + parseHex(str) { + return new Data(hexDecodeToByteArray(str)); + }, + parseBase64(str, flags) { + return new Data(base64DecodeToByteArray(str, flags)); + }, + parseLatin1(str) { + return Data.parseStr(str, StandardCharsets.ISO_8859_1); + }, + parseUTF16LE(str) { + return Data.parseStr(str, StandardCharsets.UTF_16LE); + }, + parseInputStream(stream) { + return new Data(FileUtil.toBytes(stream)); + } + }); + Object.assign(Data.prototype, { + toHex() { + return bytesToHex(this.bytes); + }, + toBytes() { + return this.bytes; + }, + toString(charset) { + return bytesToString(this.bytes, charset); + }, + toLatin1() { + return this.toString(StandardCharsets.ISO_8859_1); + }, + toUTF16LE() { + return this.toString(StandardCharsets.UTF_16LE); + }, + toUTF16() { + return this.toString(StandardCharsets.UTF_16); + }, + toBase64(flags) { + return String(Base64.encodeToString(this.bytes, flags || Base64.DEFAULT)); + }, + toDigest() { + return new Digest(this); + }, + toInputStream() { + return FileUtil.toInputStream(this.bytes); + } + }); + //摘要类 + function Digest(data) { + this.data = data; + } + Digest.digest = function(data, algorithm) { + try { + let md = MessageDigest.getInstance(algorithm); + md.update(data.toBytes()); + let hashInBytes = md.digest(); + return String(bytesToHex(hashInBytes)); + } catch (e) { + throw (e); + } + } + Object.assign(Digest.prototype, { + md5() { + return Digest.digest(this.data, "MD5"); + }, + sha256() { + return Digest.digest(this.data, "SHA-256"); + }, + md2() { + return Digest.digest(this.data, "MD2"); + }, + sha1() { + return Digest.digest(this.data, "SHA-1"); + }, + sha512() { + return Digest.digest(this.data, "SHA-512"); + }, + sha384() { + return Digest.digest(this.data, "SHA-384"); + } + }); + + + function process(operation, cipherType, input, key, option) { + option = option || {}; + validate(key, option.mode, cipherType); + if (typeof input === "string") { + input = operation === Cipher.ENCRYPT_MODE ? Data.parseUTF8(input) : Data.parseBase64(input); + } + let secretKey = new SecretKeySpec(key.toBytes(), cipherType); + let cipher = Cipher.getInstance(option.mode || cipherType); + if (option.iv != null) { + cipher.init(operation, secretKey, new IvParameterSpec(option.iv.toBytes())); + } else { + cipher.init(operation, secretKey); + } + return new Data(cipher.doFinal(input.toBytes())); + } + + const AES = { + encrypt(data, key, option) { + return result = process(Cipher.ENCRYPT_MODE, "AES", data, key, option); + + }, + + decrypt(data, key, option) { + return process(Cipher.DECRYPT_MODE, "AES", data, key, option); + } + } + + const DES = { + encrypt(data, key, option) { + return process(Cipher.ENCRYPT_MODE, "DES", data, key, option); + }, + decrypt(data, key, option) { + return process(Cipher.DECRYPT_MODE, "DES", data, key, option); + } + } + + const DESede = { + encrypt(data, key, option) { + return process(Cipher.ENCRYPT_MODE, "DESede", data, key, option); + }, + decrypt(data, key, option) { + return process(Cipher.DECRYPT_MODE, "DESede", data, key, option); + } + } + + function validate(key, mode, cipherType) { + if (key == null) { + throw new Error("Key must not be null or empty."); + } + if (mode && !mode.startsWith(cipherType)) { + throw new Error("Invalid mode."); + } + let expectedKeyLength = []; + switch (cipherType) { + case "AES": + expectedKeyLength = [16, 24, 36]; + break; + case "DESede": + expectedKeyLength = [24]; + break; + case "DES": + expectedKeyLength = [8]; + break; + default: + throw new Error("Invalid cipher type."); + } + if (!expectedKeyLength.includes(key.length)) { + throw new Error("Invalid key length. Key length must be " + expectedKeyLength.join(" or ") + " bytes for " + cipherType + "."); + } + } + /*mode + AES/CBC/PKCS5Padding + AES/CBC/NoPadding + AES/ECB/PKCS5Padding + AES/ECB/NoPadding + AES/CFB/NoPadding + AES/CFB/PKCS5Padding + AES/OFB/NoPadding + AES/OFB/PKCS5Padding + AES/CTR/NoPadding + AES/CTR/PKCS5Padding + + DES/CBC/PKCS5Padding + DES/CBC/NoPadding + DES/ECB/PKCS5Padding + DES/ECB/NoPadding + DES/CFB/NoPadding + DES/CFB/PKCS5Padding + DES/OFB/NoPadding + DES/OFB/PKCS5Padding + DES/CTR/NoPadding + DES/CTR/PKCS5Padding + + */ + function bytesToString(bytes, charset) { + return String(new jvString(bytes, charset || StandardCharsets.UTF_8)); + } + + function base64EncodeToByteArray(str, flags) { + return Base64.encode(str.getBytes(StandardCharsets.UTF_8), flags || Base64.DEFAULT); + } + + function base64DecodeToByteArray(str, flags) { + if (str == null) { + return null; + } + return Base64.decode(str, flags || Base64.DEFAULT); + } + + function hexDecodeToByteArray(cipherText) { + cipherText = String(cipherText); + let str = cipherText.toLowerCase(); + let length = str.length; + let bArr = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, length / 2); + for (let i = 0, o = 0; i < length; i += 2, o++) { + let a = str[i + 1], + b = str[i]; + if (b != "0") { + a = b + a; + } + let hexInt = Integer.parseInt(new jvString(a), 16); + let inty = hexInt > 127 ? hexInt - 255 - 1 : hexInt; + bArr[o] = inty; + } + return bArr; + } + + function bytesToHex(data) { + let strBuffer = new StringBuffer(); + for (let i = 0; i < data.length; i++) { + //strBuffer.append(Integer.toHexString(0xff & data[i])); + strBuffer.append(jvString.format("%02x", Byte(data[i]))); + } + return String(strBuffer.toString()); + } + + function toJvString(str) { + if (typeof str === "string") { + return new jvString(str); + } else { + return str; + } + } + $.exports = { + Data, + Digest, + AES, + DES, + DESede + }; +})() + + + + + let 图片解密 = function(key,iv,kiType,mode) { function hexStringToBytes(cipherText) { cipherText = String(cipherText);