772 lines
23 KiB
Plaintext
772 lines
23 KiB
Plaintext
import type { CryptoBlockMode, CryptoByteCipherOptions, CryptoCodecKind, CryptoDesOptions, CryptoDigestKind, CryptoMacKind, CryptoPaddingKind, CryptoRsaPair, CryptoTextCipherOptions, RsaOutputKind } from '../interface.uts'
|
|
|
|
const LIME_MODE_CBC = 1
|
|
const LIME_MODE_CFB = 2
|
|
const LIME_MODE_CTR = 3
|
|
const LIME_MODE_CTR_GLADMAN = 4
|
|
const LIME_MODE_ECB = 5
|
|
const LIME_MODE_OFB = 6
|
|
|
|
const LIME_PAD_PKCS7 = 1
|
|
const LIME_PAD_ANSI_X923 = 2
|
|
const LIME_PAD_ISO_10126 = 3
|
|
const LIME_PAD_ISO_97971 = 4
|
|
const LIME_PAD_NONE = 5
|
|
const LIME_PAD_ZERO = 6
|
|
|
|
const BASE64_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
|
|
|
export type CompatBridge = {
|
|
encodeText : (codec : CryptoCodecKind, plainText : string) => string,
|
|
decodeText : (codec : CryptoCodecKind, encodedText : string) => string,
|
|
digestText : (kind : CryptoDigestKind, plainText : string) => string,
|
|
signText : (kind : CryptoMacKind, secretText : string, plainText : string) => string,
|
|
aesEncryptText : (secretText : string, plainText : string, options : CryptoTextCipherOptions | null) => string,
|
|
aesDecryptText : (secretText : string, cipherText : string, options : CryptoTextCipherOptions | null) => string,
|
|
aesEncryptBytes : (secretBytes : Uint8Array, plainBytes : Uint8Array, options : CryptoByteCipherOptions | null) => Uint8Array,
|
|
aesDecryptBytes : (secretBytes : Uint8Array, cipherBytes : Uint8Array, options : CryptoByteCipherOptions | null) => Uint8Array,
|
|
desEncryptText : (secretText : string, plainText : string, options : CryptoDesOptions | null) => string,
|
|
desDecryptText : (secretText : string, cipherText : string, options : CryptoDesOptions | null) => string,
|
|
createRsaPair : (keySize : number) => CryptoRsaPair,
|
|
rsaEncryptText : (publicKey : string, plainText : string, outputKind : RsaOutputKind | null) => string,
|
|
rsaDecryptText : (privateKey : string, cipherText : string, outputKind : RsaOutputKind | null) => string,
|
|
rc4EncryptText : (secretText : string, plainText : string) => string,
|
|
rc4DecryptText : (secretText : string, cipherHexText : string) => string
|
|
}
|
|
|
|
export type CompatEncSet = {
|
|
Utf8 : CompatEncoder,
|
|
Hex : CompatEncoder,
|
|
Base64 : CompatEncoder,
|
|
Latin1 : CompatEncoder,
|
|
Utf16 : CompatEncoder,
|
|
Base64url : CompatEncoder
|
|
}
|
|
|
|
export type CompatModeSet = {
|
|
CBC : number,
|
|
CFB : number,
|
|
CTR : number,
|
|
CTRGladman : number,
|
|
ECB : number,
|
|
OFB : number
|
|
}
|
|
|
|
export type CompatPadSet = {
|
|
Pkcs7 : number,
|
|
AnsiX923 : number,
|
|
Iso10126 : number,
|
|
Iso97971 : number,
|
|
NoPadding : number,
|
|
ZeroPadding : number
|
|
}
|
|
|
|
export function createCompatBridge(
|
|
encodeText : (codec : CryptoCodecKind, plainText : string) => string,
|
|
decodeText : (codec : CryptoCodecKind, encodedText : string) => string,
|
|
digestText : (kind : CryptoDigestKind, plainText : string) => string,
|
|
signText : (kind : CryptoMacKind, secretText : string, plainText : string) => string,
|
|
aesEncryptText : (secretText : string, plainText : string, options : CryptoTextCipherOptions | null) => string,
|
|
aesDecryptText : (secretText : string, cipherText : string, options : CryptoTextCipherOptions | null) => string,
|
|
aesEncryptBytes : (secretBytes : Uint8Array, plainBytes : Uint8Array, options : CryptoByteCipherOptions | null) => Uint8Array,
|
|
aesDecryptBytes : (secretBytes : Uint8Array, cipherBytes : Uint8Array, options : CryptoByteCipherOptions | null) => Uint8Array,
|
|
desEncryptText : (secretText : string, plainText : string, options : CryptoDesOptions | null) => string,
|
|
desDecryptText : (secretText : string, cipherText : string, options : CryptoDesOptions | null) => string,
|
|
createRsaPair : (keySize : number) => CryptoRsaPair,
|
|
rsaEncryptText : (publicKey : string, plainText : string, outputKind : RsaOutputKind | null) => string,
|
|
rsaDecryptText : (privateKey : string, cipherText : string, outputKind : RsaOutputKind | null) => string,
|
|
rc4EncryptText : (secretText : string, plainText : string) => string,
|
|
rc4DecryptText : (secretText : string, cipherHexText : string) => string
|
|
) : CompatBridge {
|
|
return {
|
|
encodeText,
|
|
decodeText,
|
|
digestText,
|
|
signText,
|
|
aesEncryptText,
|
|
aesDecryptText,
|
|
aesEncryptBytes,
|
|
aesDecryptBytes,
|
|
desEncryptText,
|
|
desDecryptText,
|
|
createRsaPair,
|
|
rsaEncryptText,
|
|
rsaDecryptText,
|
|
rc4EncryptText,
|
|
rc4DecryptText
|
|
} as CompatBridge
|
|
}
|
|
|
|
function cloneBytes(input : Uint8Array) : Uint8Array {
|
|
const output = new Uint8Array(input.length)
|
|
let index = 0
|
|
while (index < input.length) {
|
|
output[index] = input[index]
|
|
index += 1
|
|
}
|
|
return output
|
|
}
|
|
|
|
function bytesToWords(input : Uint8Array) : number[] {
|
|
const output = [] as number[]
|
|
let index = 0
|
|
while (index < input.length) {
|
|
let word = 0
|
|
let offset = 0
|
|
while (offset < 4 && index + offset < input.length) {
|
|
word |= input[index + offset] << (24 - offset * 8)
|
|
offset += 1
|
|
}
|
|
output.push(word)
|
|
index += 4
|
|
}
|
|
return output
|
|
}
|
|
|
|
function byteToHex(value : number) : string {
|
|
let part = value.toString(16)
|
|
if (part.length < 2) {
|
|
part = '0' + part
|
|
}
|
|
return part
|
|
}
|
|
|
|
function bytesToHex(input : Uint8Array) : string {
|
|
let output = ''
|
|
let index = 0
|
|
while (index < input.length) {
|
|
output += byteToHex(input[index] & 0xff)
|
|
index += 1
|
|
}
|
|
return output
|
|
}
|
|
|
|
function hexValueOfChar(ch : string) : number {
|
|
const lower = ch.toLowerCase()
|
|
const code = lower.charCodeAt(0)
|
|
const actualCode = code == null ? 0 : code
|
|
if (lower >= '0' && lower <= '9') {
|
|
return actualCode - 48
|
|
}
|
|
return actualCode - 87
|
|
}
|
|
|
|
function hexToBytes(hexText : string) : Uint8Array {
|
|
const actualLength = hexText.length % 2 == 0 ? hexText.length : hexText.length - 1
|
|
const output = new Uint8Array(actualLength / 2)
|
|
let index = 0
|
|
while (index < actualLength) {
|
|
const high = hexValueOfChar(hexText.substring(index, index + 1))
|
|
const low = hexValueOfChar(hexText.substring(index + 1, index + 2))
|
|
const targetIndex = index / 2
|
|
output[targetIndex] = ((high << 4) | low) & 0xff
|
|
index += 2
|
|
}
|
|
return output
|
|
}
|
|
|
|
function base64IndexOf(ch : string) : number {
|
|
return BASE64_ALPHABET.indexOf(ch)
|
|
}
|
|
|
|
function toBase64UrlText(input : string) : string {
|
|
let output = ''
|
|
let index = 0
|
|
while (index < input.length) {
|
|
const ch = input.substring(index, index + 1)
|
|
if (ch == '+') {
|
|
output += '-'
|
|
} else if (ch == '/') {
|
|
output += '_'
|
|
} else if (ch != '=') {
|
|
output += ch
|
|
}
|
|
index += 1
|
|
}
|
|
return output
|
|
}
|
|
|
|
function fromBase64UrlText(input : string) : string {
|
|
let output = ''
|
|
let index = 0
|
|
while (index < input.length) {
|
|
const ch = input.substring(index, index + 1)
|
|
if (ch == '-') {
|
|
output += '+'
|
|
} else if (ch == '_') {
|
|
output += '/'
|
|
} else {
|
|
output += ch
|
|
}
|
|
index += 1
|
|
}
|
|
while (output.length % 4 != 0) {
|
|
output += '='
|
|
}
|
|
return output
|
|
}
|
|
|
|
function bytesToBase64(input : Uint8Array, urlSafe : boolean) : string {
|
|
let output = ''
|
|
let index = 0
|
|
while (index < input.length) {
|
|
const first = input[index] & 0xff
|
|
const hasSecond = index + 1 < input.length
|
|
const hasThird = index + 2 < input.length
|
|
const second = hasSecond ? input[index + 1] & 0xff : 0
|
|
const third = hasThird ? input[index + 2] & 0xff : 0
|
|
const block = (first << 16) | (second << 8) | third
|
|
output += BASE64_ALPHABET.substring((block >>> 18) & 0x3f, ((block >>> 18) & 0x3f) + 1)
|
|
output += BASE64_ALPHABET.substring((block >>> 12) & 0x3f, ((block >>> 12) & 0x3f) + 1)
|
|
if (hasSecond) {
|
|
output += BASE64_ALPHABET.substring((block >>> 6) & 0x3f, ((block >>> 6) & 0x3f) + 1)
|
|
} else {
|
|
output += '='
|
|
}
|
|
if (hasThird) {
|
|
output += BASE64_ALPHABET.substring(block & 0x3f, (block & 0x3f) + 1)
|
|
} else {
|
|
output += '='
|
|
}
|
|
index += 3
|
|
}
|
|
if (urlSafe) {
|
|
return toBase64UrlText(output)
|
|
}
|
|
return output
|
|
}
|
|
|
|
function normalizeBase64Text(input : string) : string {
|
|
return fromBase64UrlText(input)
|
|
}
|
|
|
|
function base64ToBytes(input : string, urlSafe : boolean) : Uint8Array {
|
|
const source = urlSafe ? normalizeBase64Text(input) : input
|
|
const output = [] as number[]
|
|
let index = 0
|
|
while (index < source.length) {
|
|
const char1 = source.substring(index, index + 1)
|
|
const char2 = source.substring(index + 1, index + 2)
|
|
const char3 = source.substring(index + 2, index + 3)
|
|
const char4 = source.substring(index + 3, index + 4)
|
|
const value1 = base64IndexOf(char1)
|
|
const value2 = base64IndexOf(char2)
|
|
const value3 = char3 == '=' ? -1 : base64IndexOf(char3)
|
|
const value4 = char4 == '=' ? -1 : base64IndexOf(char4)
|
|
const block = (value1 << 18) | (value2 << 12) | ((value3 < 0 ? 0 : value3) << 6) | (value4 < 0 ? 0 : value4)
|
|
output.push((block >>> 16) & 0xff)
|
|
if (value3 >= 0) {
|
|
output.push((block >>> 8) & 0xff)
|
|
}
|
|
if (value4 >= 0) {
|
|
output.push(block & 0xff)
|
|
}
|
|
index += 4
|
|
}
|
|
return new Uint8Array(output)
|
|
}
|
|
|
|
function latin1ToBytes(input : string) : Uint8Array {
|
|
const output = new Uint8Array(input.length)
|
|
let index = 0
|
|
while (index < input.length) {
|
|
const code = input.charCodeAt(index)
|
|
output[index] = (code == null ? 0 : code) & 0xff
|
|
index += 1
|
|
}
|
|
return output
|
|
}
|
|
|
|
function bytesToLatin1(input : Uint8Array) : string {
|
|
let output = ''
|
|
let index = 0
|
|
while (index < input.length) {
|
|
output += String.fromCharCode(input[index] & 0xff)
|
|
index += 1
|
|
}
|
|
return output
|
|
}
|
|
|
|
function utf16ToBytes(input : string) : Uint8Array {
|
|
const output = new Uint8Array(input.length * 2)
|
|
let index = 0
|
|
while (index < input.length) {
|
|
const code = input.charCodeAt(index)
|
|
const actualCode = code == null ? 0 : code
|
|
output[index * 2] = (actualCode >>> 8) & 0xff
|
|
output[index * 2 + 1] = actualCode & 0xff
|
|
index += 1
|
|
}
|
|
return output
|
|
}
|
|
|
|
function bytesToUtf16(input : Uint8Array) : string {
|
|
let output = ''
|
|
let index = 0
|
|
while (index + 1 < input.length) {
|
|
const code = ((input[index] & 0xff) << 8) | (input[index + 1] & 0xff)
|
|
output += String.fromCharCode(code)
|
|
index += 2
|
|
}
|
|
return output
|
|
}
|
|
|
|
function textToUtf8Bytes(input : string, bridge : CompatBridge) : Uint8Array {
|
|
return hexToBytes(bridge.encodeText('hex', input))
|
|
}
|
|
|
|
function utf8BytesToText(input : Uint8Array, bridge : CompatBridge) : string {
|
|
return bridge.decodeText('hex', bytesToHex(input))
|
|
}
|
|
|
|
function parseCodecBytes(kind : CryptoCodecKind, input : string, bridge : CompatBridge) : Uint8Array {
|
|
if (kind == 'utf8') {
|
|
return textToUtf8Bytes(input, bridge)
|
|
}
|
|
if (kind == 'hex') {
|
|
return hexToBytes(input)
|
|
}
|
|
if (kind == 'base64') {
|
|
return base64ToBytes(input, false)
|
|
}
|
|
if (kind == 'base64url') {
|
|
return base64ToBytes(input, true)
|
|
}
|
|
if (kind == 'latin1') {
|
|
return latin1ToBytes(input)
|
|
}
|
|
return utf16ToBytes(input)
|
|
}
|
|
|
|
function stringifyCodecBytes(kind : CryptoCodecKind, input : Uint8Array, bridge : CompatBridge) : string {
|
|
if (kind == 'utf8') {
|
|
return utf8BytesToText(input, bridge)
|
|
}
|
|
if (kind == 'hex') {
|
|
return bytesToHex(input)
|
|
}
|
|
if (kind == 'base64') {
|
|
return bytesToBase64(input, false)
|
|
}
|
|
if (kind == 'base64url') {
|
|
return bytesToBase64(input, true)
|
|
}
|
|
if (kind == 'latin1') {
|
|
return bytesToLatin1(input)
|
|
}
|
|
return bytesToUtf16(input)
|
|
}
|
|
|
|
function normalizeKeyLength(keySize : number | null) : number | null {
|
|
if (keySize == null) {
|
|
return null
|
|
}
|
|
if (keySize == 128) {
|
|
return 16
|
|
}
|
|
if (keySize == 192) {
|
|
return 24
|
|
}
|
|
if (keySize == 256) {
|
|
return 32
|
|
}
|
|
if (keySize == 16 || keySize == 24 || keySize == 32) {
|
|
return keySize
|
|
}
|
|
return 16
|
|
}
|
|
|
|
function toLimeMode(mode : number | null) : CryptoBlockMode {
|
|
if (mode == LIME_MODE_CFB) {
|
|
return 'CFB'
|
|
}
|
|
if (mode == LIME_MODE_CTR) {
|
|
return 'CTR'
|
|
}
|
|
if (mode == LIME_MODE_CTR_GLADMAN) {
|
|
return 'CTRGladman'
|
|
}
|
|
if (mode == LIME_MODE_ECB) {
|
|
return 'ECB'
|
|
}
|
|
if (mode == LIME_MODE_OFB) {
|
|
return 'OFB'
|
|
}
|
|
return 'CBC'
|
|
}
|
|
|
|
function toLimePadding(padding : number | null) : CryptoPaddingKind {
|
|
if (padding == LIME_PAD_ANSI_X923) {
|
|
return 'ANSI_X923'
|
|
}
|
|
if (padding == LIME_PAD_ISO_10126) {
|
|
return 'ISO_10126'
|
|
}
|
|
if (padding == LIME_PAD_ISO_97971) {
|
|
return 'ISO_97971'
|
|
}
|
|
if (padding == LIME_PAD_NONE) {
|
|
return 'NONE'
|
|
}
|
|
if (padding == LIME_PAD_ZERO) {
|
|
return 'ZERO'
|
|
}
|
|
return 'PKCS7'
|
|
}
|
|
|
|
function readConfigNumber(cfg : UTSJSONObject | null, key : string) : number | null {
|
|
if (cfg == null) {
|
|
return null
|
|
}
|
|
return cfg.getNumber(key)
|
|
}
|
|
|
|
function readConfigWordArray(cfg : UTSJSONObject | null, key : string) : CompatWordArray | null {
|
|
if (cfg == null) {
|
|
return null
|
|
}
|
|
const raw = cfg.get(key) as object | null
|
|
if (raw != null && raw instanceof CompatWordArray) {
|
|
return raw as CompatWordArray
|
|
}
|
|
return null
|
|
}
|
|
|
|
function buildLimeTextOptions(cfg : UTSJSONObject | null, bridge : CompatBridge) : CryptoTextCipherOptions {
|
|
const iv = readConfigWordArray(cfg, 'iv')
|
|
return {
|
|
mode: toLimeMode(readConfigNumber(cfg, 'mode')),
|
|
padding: toLimePadding(readConfigNumber(cfg, 'padding')),
|
|
ivText: iv == null ? null : utf8BytesToText(iv.toUint8Array(), bridge),
|
|
keyLength: null
|
|
} as CryptoTextCipherOptions
|
|
}
|
|
|
|
function buildLimeDesOptions(cfg : UTSJSONObject | null, bridge : CompatBridge) : CryptoDesOptions {
|
|
const iv = readConfigWordArray(cfg, 'iv')
|
|
return {
|
|
mode: toLimeMode(readConfigNumber(cfg, 'mode')),
|
|
padding: toLimePadding(readConfigNumber(cfg, 'padding')),
|
|
ivText: iv == null ? null : utf8BytesToText(iv.toUint8Array(), bridge)
|
|
} as CryptoDesOptions
|
|
}
|
|
|
|
function buildXTextOptions(mode : string, iv : string | null, keySize : number | null) : CryptoTextCipherOptions {
|
|
return {
|
|
mode: mode == 'CBC' ? 'CBC' : 'ECB',
|
|
padding: 'PKCS7',
|
|
ivText: iv,
|
|
keyLength: normalizeKeyLength(keySize)
|
|
} as CryptoTextCipherOptions
|
|
}
|
|
|
|
function buildXByteOptions(mode : string, iv : Uint8Array | null, keySize : number | null) : CryptoByteCipherOptions {
|
|
return {
|
|
mode: mode == 'CBC' ? 'CBC' : 'ECB',
|
|
padding: 'PKCS7',
|
|
ivBytes: iv,
|
|
keyLength: normalizeKeyLength(keySize)
|
|
} as CryptoByteCipherOptions
|
|
}
|
|
|
|
function buildXDesOptions(mode : string, iv : string | null) : CryptoDesOptions {
|
|
return {
|
|
mode: mode == 'CBC' ? 'CBC' : 'ECB',
|
|
padding: 'PKCS7',
|
|
ivText: iv
|
|
} as CryptoDesOptions
|
|
}
|
|
|
|
function keyToText(key : string | CompatWordArray, bridge : CompatBridge) : string {
|
|
if (typeof key == 'string') {
|
|
return key
|
|
}
|
|
if (key instanceof CompatWordArray) {
|
|
return utf8BytesToText(key.toUint8Array(), bridge)
|
|
}
|
|
return ''
|
|
}
|
|
|
|
export class CompatWordArray {
|
|
words : number[]
|
|
sigBytes : number
|
|
private rawBytes : Uint8Array
|
|
|
|
constructor(rawBytes : Uint8Array) {
|
|
this.rawBytes = cloneBytes(rawBytes)
|
|
this.words = bytesToWords(this.rawBytes)
|
|
this.sigBytes = this.rawBytes.length
|
|
}
|
|
|
|
toString(encoder : CompatEncoder | null = null) : string {
|
|
if (encoder == null) {
|
|
return bytesToHex(this.rawBytes)
|
|
}
|
|
return encoder.stringify(this)
|
|
}
|
|
|
|
toUint8Array() : Uint8Array {
|
|
return cloneBytes(this.rawBytes)
|
|
}
|
|
}
|
|
|
|
export class CompatCipherResult {
|
|
ciphertext : CompatWordArray
|
|
private serialized : string
|
|
|
|
constructor(serialized : string, cipherBytes : Uint8Array) {
|
|
this.serialized = serialized
|
|
this.ciphertext = new CompatWordArray(cipherBytes)
|
|
}
|
|
|
|
toString(encoder : CompatEncoder | null = null) : string {
|
|
if (encoder == null) {
|
|
return this.serialized
|
|
}
|
|
return this.ciphertext.toString(encoder)
|
|
}
|
|
}
|
|
|
|
export class CompatEncoder {
|
|
private kind : CryptoCodecKind
|
|
private bridge : CompatBridge
|
|
|
|
constructor(kind : CryptoCodecKind, bridge : CompatBridge) {
|
|
this.kind = kind
|
|
this.bridge = bridge
|
|
}
|
|
|
|
parse(input : string) : CompatWordArray {
|
|
return new CompatWordArray(parseCodecBytes(this.kind, input, this.bridge))
|
|
}
|
|
|
|
stringify(wordArray : CompatWordArray) : string {
|
|
return stringifyCodecBytes(this.kind, wordArray.toUint8Array(), this.bridge)
|
|
}
|
|
}
|
|
|
|
export class CompatRsaAdapter {
|
|
private bridge : CompatBridge
|
|
private publicKey : string = ''
|
|
private privateKey : string = ''
|
|
|
|
constructor(bridge : CompatBridge) {
|
|
this.bridge = bridge
|
|
}
|
|
|
|
generateKeyPair() : CryptoRsaPair {
|
|
const pair = this.bridge.createRsaPair(2048)
|
|
this.publicKey = pair.publicKey
|
|
this.privateKey = pair.privateKey
|
|
return pair
|
|
}
|
|
|
|
setPublicKey(publicKey : string) : void {
|
|
this.publicKey = publicKey
|
|
}
|
|
|
|
setPrivateKey(privateKey : string) : void {
|
|
this.privateKey = privateKey
|
|
}
|
|
|
|
encrypt(data : string) : string {
|
|
return this.bridge.rsaEncryptText(this.publicKey, data, 'base64')
|
|
}
|
|
|
|
decrypt(encryptedData : string) : string {
|
|
return this.bridge.rsaDecryptText(this.privateKey, encryptedData, 'base64')
|
|
}
|
|
|
|
getPublicKey() : string {
|
|
return this.publicKey
|
|
}
|
|
|
|
getPrivateKey() : string {
|
|
return this.privateKey
|
|
}
|
|
}
|
|
|
|
export class CompatSymmetricAdapter {
|
|
private bridge : CompatBridge
|
|
private algorithm : string
|
|
|
|
constructor(bridge : CompatBridge, algorithm : string) {
|
|
this.bridge = bridge
|
|
this.algorithm = algorithm
|
|
}
|
|
|
|
encrypt(message : string, key : string | CompatWordArray, cfg : UTSJSONObject | null = null) : CompatCipherResult {
|
|
const keyText = keyToText(key, this.bridge)
|
|
if (this.algorithm == 'DES') {
|
|
const cipherText = this.bridge.desEncryptText(keyText, message, buildLimeDesOptions(cfg, this.bridge))
|
|
return new CompatCipherResult(cipherText, parseCodecBytes('base64', cipherText, this.bridge))
|
|
}
|
|
const cipherText = this.bridge.aesEncryptText(keyText, message, buildLimeTextOptions(cfg, this.bridge))
|
|
return new CompatCipherResult(cipherText, parseCodecBytes('base64', cipherText, this.bridge))
|
|
}
|
|
|
|
decrypt(ciphertext : string, password : string | CompatWordArray, cfg : UTSJSONObject | null = null) : CompatWordArray {
|
|
const keyText = keyToText(password, this.bridge)
|
|
if (this.algorithm == 'DES') {
|
|
return new CompatWordArray(textToUtf8Bytes(this.bridge.desDecryptText(keyText, ciphertext, buildLimeDesOptions(cfg, this.bridge)), this.bridge))
|
|
}
|
|
return new CompatWordArray(textToUtf8Bytes(this.bridge.aesDecryptText(keyText, ciphertext, buildLimeTextOptions(cfg, this.bridge)), this.bridge))
|
|
}
|
|
}
|
|
|
|
export class CompatCrypto {
|
|
enc : CompatEncSet
|
|
mode : CompatModeSet
|
|
pad : CompatPadSet
|
|
AES : CompatSymmetricAdapter
|
|
DES : CompatSymmetricAdapter
|
|
RSA : CompatRsaAdapter
|
|
private bridge : CompatBridge
|
|
|
|
constructor(bridge : CompatBridge) {
|
|
this.bridge = bridge
|
|
this.enc = {
|
|
Utf8: new CompatEncoder('utf8', bridge),
|
|
Hex: new CompatEncoder('hex', bridge),
|
|
Base64: new CompatEncoder('base64', bridge),
|
|
Latin1: new CompatEncoder('latin1', bridge),
|
|
Utf16: new CompatEncoder('utf16', bridge),
|
|
Base64url: new CompatEncoder('base64url', bridge)
|
|
} as CompatEncSet
|
|
this.mode = {
|
|
CBC: LIME_MODE_CBC,
|
|
CFB: LIME_MODE_CFB,
|
|
CTR: LIME_MODE_CTR,
|
|
CTRGladman: LIME_MODE_CTR_GLADMAN,
|
|
ECB: LIME_MODE_ECB,
|
|
OFB: LIME_MODE_OFB
|
|
} as CompatModeSet
|
|
this.pad = {
|
|
Pkcs7: LIME_PAD_PKCS7,
|
|
AnsiX923: LIME_PAD_ANSI_X923,
|
|
Iso10126: LIME_PAD_ISO_10126,
|
|
Iso97971: LIME_PAD_ISO_97971,
|
|
NoPadding: LIME_PAD_NONE,
|
|
ZeroPadding: LIME_PAD_ZERO
|
|
} as CompatPadSet
|
|
this.AES = new CompatSymmetricAdapter(bridge, 'AES')
|
|
this.DES = new CompatSymmetricAdapter(bridge, 'DES')
|
|
this.RSA = new CompatRsaAdapter(bridge)
|
|
}
|
|
|
|
MD5(message : string) : CompatWordArray {
|
|
return new CompatWordArray(hexToBytes(this.bridge.digestText('md5', message)))
|
|
}
|
|
|
|
SHA1(message : string) : CompatWordArray {
|
|
return new CompatWordArray(hexToBytes(this.bridge.digestText('sha1', message)))
|
|
}
|
|
|
|
SHA256(message : string) : CompatWordArray {
|
|
return new CompatWordArray(hexToBytes(this.bridge.digestText('sha256', message)))
|
|
}
|
|
|
|
SHA512(message : string) : CompatWordArray {
|
|
return new CompatWordArray(hexToBytes(this.bridge.digestText('sha512', message)))
|
|
}
|
|
|
|
HmacSHA256(message : string, secretKey : string | CompatWordArray) : CompatWordArray {
|
|
return new CompatWordArray(hexToBytes(this.bridge.signText('sha256', typeof secretKey == 'string' ? secretKey : keyToText(secretKey, this.bridge), message)))
|
|
}
|
|
|
|
HmacSHA1(message : string, secretKey : string | CompatWordArray) : CompatWordArray {
|
|
return new CompatWordArray(hexToBytes(this.bridge.signText('sha1', typeof secretKey == 'string' ? secretKey : keyToText(secretKey, this.bridge), message)))
|
|
}
|
|
|
|
HmacSHA512(message : string, secretKey : string | CompatWordArray) : CompatWordArray {
|
|
return new CompatWordArray(hexToBytes(this.bridge.signText('sha512', typeof secretKey == 'string' ? secretKey : keyToText(secretKey, this.bridge), message)))
|
|
}
|
|
|
|
onError(_callback : (err : IUniError) => void) : void {
|
|
}
|
|
}
|
|
|
|
export function createCompatCrypto(bridge : CompatBridge) : CompatCrypto {
|
|
return new CompatCrypto(bridge)
|
|
}
|
|
|
|
export function base64EncodeCompat(bridge : CompatBridge, input : string) : string {
|
|
return bridge.encodeText('base64', input)
|
|
}
|
|
|
|
export function base64DecodeCompat(bridge : CompatBridge, input : string) : string {
|
|
return bridge.decodeText('base64', input)
|
|
}
|
|
|
|
export function md5Compat(bridge : CompatBridge, input : string) : string {
|
|
return bridge.digestText('md5', input)
|
|
}
|
|
|
|
export function sha1Compat(bridge : CompatBridge, input : string) : string {
|
|
return bridge.digestText('sha1', input)
|
|
}
|
|
|
|
export function sha256Compat(bridge : CompatBridge, input : string) : string {
|
|
return bridge.digestText('sha256', input)
|
|
}
|
|
|
|
export function sha512Compat(bridge : CompatBridge, input : string) : string {
|
|
return bridge.digestText('sha512', input)
|
|
}
|
|
|
|
export function hmacSha1Compat(bridge : CompatBridge, key : string, data : string) : string {
|
|
return bridge.signText('sha1', key, data)
|
|
}
|
|
|
|
export function hmacSha256Compat(bridge : CompatBridge, key : string, data : string) : string {
|
|
return bridge.signText('sha256', key, data)
|
|
}
|
|
|
|
export function hmacSha512Compat(bridge : CompatBridge, key : string, data : string) : string {
|
|
return bridge.signText('sha512', key, data)
|
|
}
|
|
|
|
export function aesEncryptCompat(bridge : CompatBridge, key : string, data : string, mode : string = 'ECB', iv : string | null = null, keySize : number | null = 16) : string {
|
|
return bridge.aesEncryptText(key, data, buildXTextOptions(mode, iv, keySize))
|
|
}
|
|
|
|
export function aesDecryptCompat(bridge : CompatBridge, key : string, data : string, mode : string = 'ECB', iv : string | null = null, keySize : number | null = 16) : string {
|
|
return bridge.aesDecryptText(key, data, buildXTextOptions(mode, iv, keySize))
|
|
}
|
|
|
|
export function aesEncryptBytesCompat(bridge : CompatBridge, key : Uint8Array, data : Uint8Array, mode : string = 'ECB', iv : Uint8Array | null = null, keySize : number | null = 16) : Uint8Array {
|
|
return bridge.aesEncryptBytes(key, data, buildXByteOptions(mode, iv, keySize))
|
|
}
|
|
|
|
export function aesDecryptBytesCompat(bridge : CompatBridge, key : Uint8Array, data : Uint8Array, mode : string = 'ECB', iv : Uint8Array | null = null, keySize : number | null = 16) : Uint8Array {
|
|
return bridge.aesDecryptBytes(key, data, buildXByteOptions(mode, iv, keySize))
|
|
}
|
|
|
|
export function desEncryptCompat(bridge : CompatBridge, key : string, data : string, mode : string = 'ECB', iv : string | null = null) : string {
|
|
return bridge.desEncryptText(key, data, buildXDesOptions(mode, iv))
|
|
}
|
|
|
|
export function desDecryptCompat(bridge : CompatBridge, key : string, data : string, mode : string = 'ECB', iv : string | null = null) : string {
|
|
return bridge.desDecryptText(key, data, buildXDesOptions(mode, iv))
|
|
}
|
|
|
|
export function generateRsaKeyPairCompat(bridge : CompatBridge, keySize : number = 2048) : CryptoRsaPair {
|
|
return bridge.createRsaPair(keySize)
|
|
}
|
|
|
|
export function rsaEncryptCompat(bridge : CompatBridge, publicKey : string, data : string) : string {
|
|
return bridge.rsaEncryptText(publicKey, data, 'base64')
|
|
}
|
|
|
|
export function rsaDecryptCompat(bridge : CompatBridge, privateKey : string, data : string) : string {
|
|
return bridge.rsaDecryptText(privateKey, data, 'base64')
|
|
}
|
|
|
|
export function rc4EncryptCompat(bridge : CompatBridge, key : string, data : string) : string {
|
|
return bridge.rc4EncryptText(key, data)
|
|
}
|
|
|
|
export function rc4DecryptCompat(bridge : CompatBridge, key : string, data : string) : string {
|
|
return bridge.rc4DecryptText(key, data)
|
|
}
|