diff options
author | Minteck <contact@minteck.org> | 2023-01-10 14:54:04 +0100 |
---|---|---|
committer | Minteck <contact@minteck.org> | 2023-01-10 14:54:04 +0100 |
commit | 99c1d9af689e5325f3cf535c4007b3aeb8325229 (patch) | |
tree | e663b3c2ebdbd67c818ac0c5147f0ce1d2463cda /school/node_modules/pronote-api/src/cipher.js | |
parent | 9871b03912fc28ad38b4037ebf26a78aa937baba (diff) | |
download | pluralconnect-99c1d9af689e5325f3cf535c4007b3aeb8325229.tar.gz pluralconnect-99c1d9af689e5325f3cf535c4007b3aeb8325229.tar.bz2 pluralconnect-99c1d9af689e5325f3cf535c4007b3aeb8325229.zip |
Update - This is an automated commit
Diffstat (limited to 'school/node_modules/pronote-api/src/cipher.js')
-rw-r--r-- | school/node_modules/pronote-api/src/cipher.js | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/school/node_modules/pronote-api/src/cipher.js b/school/node_modules/pronote-api/src/cipher.js new file mode 100644 index 0000000..350de5b --- /dev/null +++ b/school/node_modules/pronote-api/src/cipher.js @@ -0,0 +1,118 @@ +const forge = require('node-forge'); +const pako = require('pako'); + +function initCipher(session, keyModulus, keyExponent) +{ + session.aesIV = generateIV(); + + session.publicKey = forge.pki.rsa.setPublicKey( + new forge.jsbn.BigInteger(keyModulus, 16), + new forge.jsbn.BigInteger(keyExponent, 16) + ); +} + +function cipher(session, data, { key, compress, disableIV } = {}) +{ + data = forge.util.encodeUtf8('' + data); + if (compress && !session.disableCompress) { + data = deflate(data); + } + + const cipher = createCipher(session, key, false, disableIV); + cipher.update(new forge.util.ByteBuffer(data)); + + return cipher.finish() && cipher.output.toHex(); +} + +function decipher(session, data, { compress, scrambled, key, asBytes } = {}) +{ + const cipher = createCipher(session, key, true); + cipher.update(new forge.util.ByteBuffer(forge.util.hexToBytes(data))); + + let result = cipher.finish() && cipher.output.bytes(); + if (compress && !session.disableCompress) { + result = inflate(result); + } + + result = forge.util.decodeUtf8(result); + + if (scrambled) { + const unscrambled = new Array(result.length); + for (let i = 0; i < result.length; i += 1) { + if (i % 2 === 0) { + unscrambled.push(result.charAt(i)); + } + } + + return unscrambled.join(''); + } + + if (asBytes) { + const buffer = new forge.util.ByteBuffer(); + const split = result.split(','); + + for (let i = 0; i < split.length; i++) { + buffer.putInt(parseInt(split[i])); + } + + return buffer; + } + + return result; +} + +function createCipher(session, key, decipher, disableIV = false) +{ + if (!key) { + key = session.aesKey || new forge.util.ByteBuffer(); + } + + const cipher = forge.cipher[decipher ? 'createDecipher' : 'createCipher']('AES-CBC', md5(key)); + const iv = disableIV ? new forge.util.ByteBuffer() : md5(session.aesIV); + + cipher.start({ iv }); + + return cipher; +} + +function md5(buffer) +{ + return forge.md.md5.create().update(buffer.bytes()).digest(); +} + +function deflate(data) +{ + return pako.deflateRaw(new forge.util.ByteBuffer(data).toHex(), { level: 6, to: 'string' }); +} + +function inflate(data) +{ + return pako.inflateRaw(data, { to: 'string' }); +} + +function generateIV() +{ + return new forge.util.ByteBuffer(forge.random.generate(16)); +} + +function getUUID(session, iv) +{ + return forge.util.encode64(session.publicKey.encrypt(iv.bytes()), 64); +} + +function getLoginKey(username, password, scramble, fromCas) +{ + const hash = forge.md.sha256.create().update(scramble || '').update(forge.util.encodeUtf8(password)).digest(); + const key = (fromCas ? '' : username.toLowerCase()) + hash.toHex().toUpperCase(); + + return new forge.util.ByteBuffer(forge.util.encodeUtf8(key)); +} + +module.exports = { + initCipher, + + cipher, + decipher, + getUUID, + getLoginKey +}; |