Cette API n'est absolument pas terminée, nous sommes deux ou trois à avancer dessus de temps en temps pour comprendre comment l'API Qrcode de pronote fonctionne pour arriver à l'utiliser dans d'autres applications non officielles. Ce repo permet de partager les résultats
L'idéal serait de pouvoir faire quelque chose comme ça :
const pronote = require('pronote-api');
const qrcode = require('pronote-qrcode-api');
qrcode.login(buffer, code).then((data) => { // buffer est l'image du qrcode, code est le JETON_4_CHIFFRE
// data contient le sessionID, etc. les paramÚtres listés ici : https://github.com/Litarvan/pronote-api/blob/master/src/session.js#L28
const session = new pronote.Session(data);
session.homeworks(); // par exemple
})
mais en réalité ça ne sera pas extactement comme ça (le login renverra un login et un mdp avec lesquels on se connectera)
Lancer le script qui extrait quelques infos
node index.js --input qrcode.png --code 1111
- QRCode scanné. Ce QRCode renvoie un JSON contenant plusieurs informations:
{
jeton: 'JETON_SUPER_LONG',
login: 'JETON_MOYEN_LONG',
url: 'https://0310047h.index-education.net/pronote/mobile.eleve.html'
}
- Pronote demande le code d'accÚs à 4 chiffres rentré précédemment par l'utilisateur (qu'on appelera
JETON_4_CHIFFRE
).
Le login est toujours la mĂȘme chaine de caractĂšres pour un mĂȘme compte, encodĂ©e avec le JETON_4_CHIFFRE
passé lors de la création du QRCode.
Le jeton est aussi encodé avec le JETON_4_CHIFFRE
, mais il est différent pour chaque QRCode.
Ces deux donnĂ©es (login et jeton) sont - lorsqu'ils sont dĂ©chiffrĂ©s - respectivement un identifiant et un mot de passe Pronote. Vous ne pouvez cependant pas les entrer directement (mĂȘme dĂ©chiffrĂ©s) sur le site web Pronote, car un protocole particulier est utilisĂ©.
- A partir de l'URL Pronote (obtenue depuis le QR Code) on peut effectuer un appel vers cette URL:
// https://0310047h.index-education.net/pronote/infoMobileApp.json?id=0D264427-EEFC-4810-A9E9-346942A862A4
{
modeModif: true,
version: [ 2020, 0, 2, 5 ],
date: '2021-01-20T11:48:47.694Z',
CAS: {
actif: true,
casURL: 'https://cas.mon-ent-occitanie.fr',
jetonCAS: 'JETON_SUPER_LONG_QUI_CHANGE_A_CHAQUE_RAFRAICHISSEMENT'
},
espaces: [
{ nom: 'Espace Direction', URL: 'mobile.direction.html' },
{ nom: 'Espace Professeurs', URL: 'mobile.professeur.html' },
{ nom: 'Espace Vie scolaire', URL: 'mobile.viescolaire.html' },
{ nom: 'Espace Parents', URL: 'mobile.parent.html' },
{ nom: 'Espace Accompagnants', URL: 'mobile.accompagnant.html' },
{ nom: 'Espace ĂlĂšves', URL: 'mobile.eleve.html' }
],
nomEtab: 'LYCEE OZENNE'
}
A noter : le paramĂštre ID (0D264427-EEFC-4810-A9E9-346942A862A4
) est une constante et ne varie pas d'un Ă©tablissement Ă l'autre.
Le code utilisé par Pronote pour déchifrer le login et le MDP est le suivant :
var lLoginDecode = GCryptage.decrypter({
genreCryptage: EGenreCryptage.AES,
chaine: aLogin,
cle: GCryptage.getBuffer(aCode),
iv: GCryptage.getBuffer(""),
});
var lJetonDecode = GCryptage.decrypter({
genreCryptage: EGenreCryptage.AES,
chaine: aJeton,
cle: GCryptage.getBuffer(aCode),
iv: GCryptage.getBuffer(""),
});
La classe GCryptage contient une fonction decrypter
qui est un déchiffreur utilisant le protocole AES-CBC
avec un padding PKCS 7
.
Il vous suffit donc pour déchiffrer le login et le mdp d'utiliser n'importe quel module de déchiffrement AES supportant le padding PKCS7, et de passer :
- Ce que vous souhaitez déchiffrer (le jeton ou le login) : attention, ces derniers sont encodés en HEX.
- l'IV Ă utiliser est un byte vide (0000000000000000)
- le mot de passe est le
JETON_4_CHIFFRE
. Vous devez utiliser celui-ci en tant que clé hashée en MD5.
Vous obtiendrez donc un login (déchiffrement du JETON_MOYEN_LONG
) et un mot de passe (déchiffrement du JETON_SUPER_LONG
).
Voici donc les Ă©tapes Ă suivre pour se connecter Ă l'aide d'un QR Code
- DĂ©chiffrer le login Ă l'aide du PIN et du
JETON_MOYEN_LONG
- DĂ©chiffrer le MDP Ă l'aide du PIN et du
JETON_SUPER_LONG
Vous devez générer un UUID pour votre appareil à l'aide d'un module de génération d'UUID quelconque. Ce dernier sera utilisé par la suite dans le protocole pour fingerprint votre appareil.
Pronote s'en sert visiblement pour vĂ©rifier que personne d'autre n'utilisera le jeton de connexion qui sera ensuite fourni Ă chaque requĂȘte de connexion.
Ca ne tient qu'à vous, mais essayez de générer un UUID au maximum sécurisé.
Je n'ai pas la place de résumer ce dernier ici, je vous conseille donc de lire l'excellente documentation fournie par Bain.
La différence par rapport à une connexion classique est qu'il faudra modifier le JSON envoyé lors de la phase d'Identification :
{
"nom": "Identification",
"session": "<session_id>", // int
"numeroOrdre": "<numero_ordre>",
"donneesSec": {
"donnees": {
"genreConnexion": "<connection_type>", // int
"genreEspace": "<espace_id>", // int
"identifiant": "<username>",
"pourENT": "<using_ent>", // bool
"enConnexionAuto": false,
"demandeConnexionAuto": false,
"demandeConnexionAppliMobile": true,
"demandeConnexionAppliMobileJeton": true,
"uuidAppliMobile": "<VOTRE_UUID>",
"loginTokenSAV": ""
}
}
}
demandeConnexionAppliMobile
et demandeConnexionAppliMobileJeton
doivent impĂ©rativement ĂȘtre dĂ©finis sur true
. Autrement vous ne parviendrez pas Ă vous connecter car Pronote pensera que vous vous connectez normalement (avec des identifiants normaux).
<VOTRE_UUID>
est l'UUID généré plus tÎt et <username>
votre identifiant déchiffré plus tÎt à l'aide du JETON_MOYEN_LONG
.
Vous remarquerez que vous n'avez entré votre mot de passe nulle part. C'est parce que le jeton est un mot de passe temporaire envoyé par Pronote. AprÚs la phase d'Identification, vous devrez procéder à la phase d'Authentification.
Suivez les instructions fournies par Bain mais prĂȘtez surtout attention Ă la chose suivante : Le JSON contiendra :
{
"nom": "Authentification",
"session": "<session_id>",
"numeroOrdre": "<numero_ordre>",
"donneesSec": {
"donnees": {
"jetonConnexionAppliMobile" : <JETON>,
"libelleUtil": "<name_of_user>",
"cle": "<long_cle_string>",
"derniereConnexion": {
...
}
},
"nom": "Authentification"
}
}
Vous devez sauvegarder le jetonConnexionAppliMobile
. Ce dernier est en fait votre nouveau mot de passe. Celui que vous devrez utiliser à la prochaine connexion. Et vous recevrez un nouveau jeton de connexion à chaque connexion et devrez remplacer le précédent.
Vous ĂȘtes normalement connectĂ©, et tout se passera bien si vous avez suivi scrupuleusement les indications prĂ©cĂ©dentes :).