funky-framadate-front/src/app/features/shared/components/ui/static-pages/ciphering/ciphering.component.ts

303 lines
7.7 KiB
TypeScript

import { Component, OnInit } from '@angular/core';
import CipherLib from './lib_cipher';
// eslint-disable-next-line @typescript-eslint/no-var-requires
// documentation:
// https://medium.com/@spatocode/symmetric-encryption-in-javascript-bcb5fd14c273
// https://nodejs.org/api/crypto.html
// https://preview.npmjs.com/package/ecma-nacl
@Component({
selector: 'app-ciphering',
templateUrl: './ciphering.component.html',
styleUrls: ['./ciphering.component.scss'],
})
export class CipheringComponent implements OnInit {
public plainText = 'coucou !';
// public plainText = '1234';
public cipheredText =
'121-127-42-110-127-42-122-121-115-128-124-111-125-107-118-127-126-42-118-111-125-42-122-115-122-121-118-111';
public algorithm = 'aes-192-cbc';
public salt = 'ou du poivre heh';
public initial_vector = '';
public key;
public otherCipheredText = 'le texte à chiffrer, coucou !';
public alphab: string;
public prem: number;
public dico: string[];
public separatedCouples: any[];
public codingMatrice: string = '2 3 5 8';
private cipheredTextCIL: string;
constructor() {
this.alphab = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 .+-*/_!?,éèêëàçôî'âù()@&$";
this.prem = this.alphab.length;
this.dico = this.alphab.split('');
}
ngOnInit(): void {
this.encrypt(this.codingMatrice, this.plainText);
}
// ---------------------- make unreadable ----------------------
get simpleCipheredText() {
return this.convertTextToInt(this.plainText);
}
get simpleCipheredTextWithSalt() {
return this.convertTextToInt(this.salt + this.plainText);
}
get simpleCipheredTextWithSpreadSalt() {
return this.convertTextToIntMixedSalt(this.salt + this.plainText);
}
get simpleCipheredTextWithHashedSalt() {
return this.convertTextToIntMixedSalt(this.md5(this.salt) + this.plainText);
}
get simpleCipheredTextWithHashedSpreadSalt() {
return this.convertTextToIntMixedSalt(this.md5(this.salt) + this.plainText);
}
get layerOnSpread() {
return this.convertIntToText(this.simpleCipheredTextWithHashedSalt, false);
}
// ---------------------- make readable ----------------------
get simpleDeCipheredText() {
return this.convertIntToText(this.cipheredText);
}
get simpleDeCipheredTextWithSalt() {
return this.convertIntToText(this.salt + this.cipheredText);
}
get simpleDeCipheredTextWithSpreadSalt() {
return this.convertIntToTextMixedSalt(this.salt + this.cipheredText);
}
// ---------------------- conversions ----------------------
/**
* chiffrer avec la méthode du CIL-gometz
* avec une matrice
* @param someText
*/
encrypt(matriceDefinition, messageToCipher) {
if (!matriceDefinition || !messageToCipher) {
return null;
}
let cipheredText = '';
const lcpl = this.separecpl(this.filterCharacters(messageToCipher));
this.separatedCouples = lcpl;
console.log('lcpl', lcpl);
console.log('this.dico', this.dico);
/**
* Pour chaque couple de caractères
* on crée le couple d'indices de ces caractères
* On applique la matrice au couple d'indices
* et on en déduit le couple de caractères codés (ou décodés)
* qu'on accumule dans la chaine msgout
*/
lcpl.forEach((couple) => {
console.log('couple', couple);
const cplnum = [this.dico.indexOf(couple[0]), this.dico.indexOf(couple[1])];
console.log('cplnum', cplnum);
const cplnumout = this.applique(matriceDefinition, cplnum);
console.log('cplnumout', cplnumout);
const cplout = [this.alphab[cplnumout[0]], this.alphab[cplnumout[1]]];
console.log('cplout', cplout);
cipheredText += cplout[0];
cipheredText += cplout[1];
});
console.log('cipheredText', cipheredText);
this.cipheredTextCIL = cipheredText;
return cipheredText;
}
/**
* séparation d'une chaine de caractères en liste de couples de caractères
* @param msg
*/
separecpl(msg) {
/**
* Produit une liste formée des couples de caractères de la chaine
msg reçue en argument.
Dans le cas où le nb de caractères de la chaine est impair,
un underscore est ajouté en fin de chaine de façon à pouvoir
inclure le dernier caractère dans un couple.
*/
const nbcar = msg.length;
if (nbcar % 2) {
msg += '_';
}
const coupleList = [];
let i = 0;
while (i < nbcar) {
coupleList.push([msg[i], msg[i + 1]]);
i += 2;
}
return coupleList;
}
/**
* calcul de l'inverse de d dans Z/pZ
* @param d
* @param p
*/
invdet(d, p) {
let inv = 1;
while ((d * inv) % p !== 1) {
inv++;
}
return inv;
}
/**
* inversion de matrice
* @param matriceString
* @param p
*/
invmat(matriceString: string, p) {
const [a, b, c, d] = this.convertStringToMatrix(matriceString);
const mul = this.invdet(a * d - b * c, p);
return [(d * mul) % p, (-b * mul) % p, (-c * mul) % p, (a * mul) % p];
}
applique(mat, cplnum) {
const [a, b, c, d] = this.convertStringToMatrix(mat);
const [x, y] = cplnum;
const xout = (a * x + b * y) % this.prem;
const yout = (c * x + d * y) % this.prem;
return [xout, yout];
}
/**
* Pour chaque caractère de la chaine msg, on vérifie qu'il est
dans l'alphabet des caractères autorisés : si oui on le garde,
sinon on le remplace par un underscore
* @param monTexte
*/
filterCharacters(monTexte) {
const convertedText = monTexte.split('').map((letter) => {
if (this.alphab.indexOf(letter) === -1) {
letter = '_';
}
return letter;
});
return convertedText.join('');
}
/**
* on entre une définition de matrice en écrivant 4 nombres dans un input
* @param stringMatrix
*/
convertStringToMatrix(stringMatrix: string) {
return stringMatrix.replace(',', ' ').replace(' ', ' ').slice(' ');
}
/**
* chiffrer avec la méthode du CIL-gometz
* @param someText
*/
decrypt(sometext) {
return sometext;
}
convertTextToInt(value) {
let result = '';
for (let i = 0; i < value.length; i++) {
if (i < value.length - 1) {
result += value.charCodeAt(i) + 10;
result += '-';
} else {
result += value.charCodeAt(i) + 10;
}
}
return result;
}
convertIntToText(value, removeBeginning = true) {
let result = '';
const array = value.split('-');
for (let i = 0; i < array.length; i++) {
result += String.fromCharCode(array[i] - 10);
}
// remove salt characters
if (removeBeginning) {
result = result.slice(this.salt.length, -1);
}
return result;
}
convertTextToIntMixedSalt(value) {
let result = '';
let saltIndex = 0;
for (let i = 0; i < value.length; i++) {
if (i < value.length - 1) {
result += value.charCodeAt(i) + 10 + this.salt.charCodeAt(saltIndex);
result += '-';
} else {
result += value.charCodeAt(i) + 10 + this.salt.charCodeAt(saltIndex);
}
saltIndex++;
if (saltIndex >= this.salt.length) {
saltIndex = 0;
}
}
return result;
}
convertIntToTextMixedSalt(value) {
let result = '';
const array = value.split('-');
let saltIndex = -1;
for (let i = 0; i < array.length; i++) {
// console.log(
// 'encodage',
// i,
// value.charCodeAt(i),
// saltIndex,
// this.salt.charCodeAt(saltIndex),
// value.charCodeAt(i) + 10 + this.salt.charCodeAt(saltIndex)
// );
result += String.fromCharCode(array[i] - 10 - this.salt.charCodeAt(saltIndex));
if (saltIndex > this.salt.length) {
saltIndex = 0;
} else {
saltIndex++;
}
}
// remove salt characters
return result.slice(this.salt.length);
}
md5(someText) {
return CipherLib.md5(someText);
}
getEntropy(s) {
let sum = 0,
len = s.length;
this.process(s, (k, f) => {
const p = f / len;
sum -= (p * Math.log(p)) / Math.log(2);
});
return sum;
}
process(s, evaluator) {
let h = Object.create(null),
k;
s.split('').forEach((c) => {
(h[c] && h[c]++) || (h[c] = 1);
});
if (evaluator) for (k in h) evaluator(k, h[k]);
return h;
}
}