# GLib/Objectifs

import java.math.*;
Classe implementant l'algorithme de chiffrement Rivest Shamir Adleman (RSA)
public class RSA {
/** * Cle publique ou cle de chiffrement */ private Key Ke ;
/** * Cle privee ou cle de dechiffrement */ private Key Kd ;
/** * Construit une instance de RSA avec les deux parametres comme cle publique et privee. * @param Ke Cle publique de l'instance * @param Kd Cle privee de l'instance * @throws Exception Erreur lancee lorsque l'exécution du code ne s'est pas deroule correctement. * @see {@link #setKeys(Key, Key)} */ public RSA(Key Ke, Key Kd) throws Exception {
setKeys(Ke,Kd);
/** * Cosntruit une instance de RSA avec (e,n) comme cle publique et (d,n) comme cle privee. * @param e Exposant de chiffrement. * @param n Modulo * @param d Exposant de dechiffrement * @throws Exception Erreur lancee lorsque l'exécution du code ne s'est pas deroule correctement. * @see {@link #setKeys(Key, Key)} */ public RSA(BigInteger e, BigInteger n , BigInteger d) throws Exception{ setKeys(new Key(e,n),new Key(d,n)); }
Affecte les deux parametres comme nouvelles cles utilisees par l'instance courante
* @param Ke Nouvelle cle publique * @param Kd Nouvelle cle privee * @throws Exception Erreur lancee lorsque l'exécution du code ne s'est pas deroule correctement. */ public void setKeys(Key Ke, Key Kd) throws Exception { if(Ke==null || Kd==null) throw new Exception("L'une ou l'autre des deux cles est/sont incorrecte(s)");
if(Ke.getModulo!=Kd.getModulo) throw new Exception("Les deux cles n'ont pas le meme modulo"); BigInteger phi = RSAUtil.phi(Ke.getModulo) ; if(Ke.getExponent.compareTo(BigInteger.ONE)<=0 || Ke.getExponent.compareTo(phi)>=0) throw new Exception("L'exposant de la cle publique est incorrect"); if(Kd.getExponent.compareTo(BigInteger.ONE)<=0 || Kd.getExponent.compareTo(phi)>=0) throw new Exception("L'exposant de la cle privee est incorrect"); this.Ke = Ke ; this.Kd = Kd ; }
Affecte (e,n) comme nouvelle cle publique et (d,n) comme nouvelle cle privee.
* @param e Exposant de chiffrement. * @param n Modulo * @param d Exposant de dechiffrement. * @throws Exception Erreur lancee lorsque l'exécution du code ne s'est pas deroule correctement. * @see {@link #setKeys(Key, Key)} */ public void setKeys(BigInteger e, BigInteger n, BigInteger d) throws Exception { setKeys(new Key(e,n),new Key(d,n)); }
/** * @return La cle publique utilisee par l'instance de RSA. */ public Key getPublicKey { return this.Ke; }
/** * @return La cle private utilisee par l'instance de RSA */ public Key getPrivateKey { return this.Kd; }
/** * Chiffre le message et retourne son chiffre. * @param message Message a chiffrer. * @return Chiffre du parametre * @throws Exception Erreur lancee lorsque l'exécution du code ne s'est pas deroule correctement. */ public BigInteger encrypt(BigInteger message) throws Exception{ //if(message.compareTo(BigInteger.ZERO)<0 || message.compareTo(Ke.getModulo.subtract(BigInteger.ONE))>0) throw new Exception("Le message ne peut etre chiffre, car "+message+" n'est pas dans l'intervalle ferme [0,"+(Ke.getModulo.subtract(BigInteger.ONE))+"]"); if(message.compareTo(BigInteger.ZERO)<0) throw new Exception("Le message ne peut etre chiffre, car il est negatif "); if(message.compareTo(Ke.getModulo)<0) return RSAUtil.modularPower(message, Ke.getExponent, Ke.getModulo) ; else{ int incr = Ke.getModulo.toString.length -1 ; if(incr<=0) throw new Exception("Le message ne peut etre decoupe de telle sorte qu'il soit dans [0,"+Ke.getModulo.subtract(BigInteger.ONE)+"]"); String param = message.toString; if((param.length%incr)!=0){ int count = incr - (param.length%incr) ; for(int i=1;i<=count;i++) param = "0"+param ; } int begin = 0 ; String result = ""; //System.out.print("algo crypted : "); while(begin<param.length){ int end = ( (begin+incr)<param.length)? (begin+incr):param.length; BigInteger aux = new BigInteger(param.substring(begin, end)); String value = (RSAUtil.modularPower(aux, Ke.getExponent, Ke.getModulo)).toString; if(value.length>(incr+1)) throw new Exception("Erreur Conception Interne"); int size = (incr+1) - value.length; for(int i=1;i<=size;i++) value = "0"+value; //System.out.print("("+aux+","+value+") "); result+=value; begin+=incr;
} //System.out.println; return (new BigInteger(result)); } }
public String toString{ return ("[ Public Key = "+Ke+","+" Private Key = "+Kd+" ]"); }
/** * Dechiffre le message et retourne le message en clair. * @param message Message a chiffrer. * @return Dechiffre du parametre * @throws Exception Erreur lancee lorsque l'exécution du code ne s'est pas deroule correctement. */ public BigInteger decrypt(BigInteger message) throws Exception { //if(message.compareTo(BigInteger.ZERO)<0 || message.compareTo(Kd.getModulo.subtract(BigInteger.ONE))>0) throw new Exception("Le message ne peut etre dechiffre, car "+message+" n'est pas dans l'intervalle ferme [0,"+(Kd.getModulo.subtract(BigInteger.ONE))+"]"); if(message.compareTo(BigInteger.ZERO)<0) throw new Exception("Le message ne peut etre chiffre, car il est negatif "); if(message.compareTo(Kd.getModulo)<0) return RSAUtil.modularPower(message, Kd.getExponent, Kd.getModulo) ; else{ int incr = Ke.getModulo.toString.length ; if(incr<=0) throw new Exception("Le message ne peut etre decoupe de telle sorte qu'il soit dans [0,"+Ke.getModulo.subtract(BigInteger.ONE)+"]"); String param = message.toString; if( (param.length%incr)!=0){ int count = incr - (param.length%incr) ; for(int i=1;i<=count;i++) param = "0"+param; } int begin = 0 ; String result = ""; //System.out.print("algo decrypted : "); while(begin<param.length){ BigInteger aux = new BigInteger(param.substring(begin, begin+incr)); //BigInteger value = RSAUtil.modularPower(aux, Kd.getExponent, Kd.getModulo) ; String value = (RSAUtil.modularPower(aux, Kd.getExponent, Kd.getModulo)).toString ; if(value.length<(incr-1)){ int count = incr-1 - value.length ; for(int i=1;i<=count;i++) value = "0"+value; } //System.out.print("("+aux+","+value+") "); result += value; begin+=incr; } //System.out.println;
return (new BigInteger(result)); } }
public static void main(String arg) throws Exception {
String message = "<document> <titre>Test</titre> <content>Le reste n'a rien avoir et je suis épuisé</content> </document>"; System.out.println("Message a chiffrer = "+message);
BigInteger number = RSAUtil.stringToNumber(message);
System.out.println("number = "+number);
BigInteger primes = RSAUtil.generateTwoPrimes(5); System.out.println("p = "+primes[0]+"; q="+primes[1]);
Key keys = RSAUtil.buildKeysOf(primes[0], primes[1]); RSA rsa = new RSA(keys[0],keys[1]); System.out.println(rsa);
BigInteger crypted = rsa.encrypt(number); System.out.println("crypted = "+crypted);
String answer = RSAUtil.numberToString(crypted); System.out.println("Valeur ascii crypted = "+answer);
BigInteger decrypted = rsa.decrypt(crypted); System.out.println("decrypted = "+decrypted);
//System.out.println("(decrypted == number) = "+(decrypted.compareTo(number)==0));
String ans = RSAUtil.numberToString(decrypted); System.out.println("Valeur Ascii decrypted = "+ans); } }