Implementacin del algoritmo de encriptacin RSA en Java
Retomando un poco la temtica principal inicial de este blog: la programacin en Java, y ms an
tocando temas tan excitantes como la criptografa, la siguiente entrada pretende que aprendas varias cosillas: Lo bsico acerca del algoritmo de encriptacin R! "#emplos de programacin en Java $onocer algunas funciones y clases interesantes del !%& J'" !prender a crear un front(end en )ing * algunas cosillas ms+++ !s que la informacin que pondr, a continuacin, no solamente ense-ar a los estudiantes y aficionados a .implementar el algoritmo R! en Java., sino que les ayudar a comprender muc/o me#or otros temas muy comunes en la .programacin de aprendi0a#e.+ Al grano... qu es RSA? 1o tiene muc/o sentido extenderme en este tema, que en realidad no es realmente lo que me preocupa ense-ar en esta entrada, pero dado que la temtica sobre la cual correr nuestra aplicacin es R!, es necesario que est,n enterados acerca del mismo+ 2astante informacin /ay ya en la red, y al final pondr, las fuentes de informacin que recomiendo, de momento podemos comen0ar con un extracto de texto tomado de la 3i4ipedia: El sistema criptogrfico con clave pblica RSA es un algoritmo asimtrico cifrador de bloques, que utiliza una clave pblica, la cual se distribuye (en forma autenticada preferentemente), y otra privada, la cual es guardada en secreto por su propietario. Una clave es un nmero de gran tamao, que una persona puede conceptualizar como un mensae digital, como un arc!ivo binario o como una cadena de bits o bytes. "uando se env#a un mensae, el emisor busca la clave pblica de cifrado del receptor y una vez que dic!o mensae llega al receptor, ste se ocupa de descifrarlo usando su clave oculta. $os mensaes enviados usando el algoritmo %&' se representan mediante nmeros y el funcionamiento se basa en el producto de dos nmeros primos grandes (mayores que () ()) ) elegidos al azar para conformar la clave de descifrado. %rofundicemos entonces en el tema de R!+++ Cmo se generan las claves RSA? upongamos que .5auricio. desea permitir que .6oracio. le enve un mensa#e cifrado sobre un canal inseguro+ Lo primero que /a de /acer es generar los pares de claves pblica 7n,e8 y privada 7n,d8: "legimos dos nmeros grandes para p y q 7entre ms grandes es ms segura la encriptacin, pero es ms demorado el proceso de encriptar9desencriptar8 que sean diferentes y totalmente independientes el uno del otro+ $alculamos n*p+q $alculamos la funcin de :otient de n: totient(n)*(p,()+(q,() "legimos un entero e, de tal forma que ; < e < totient(n) y adems que sea coprimo con totient(n) $alculamos un d, de tal forma que d+e*( mod totient(n) La clave pblica ser entonces 7n,e8 y la privada 7n,d8 "n dic/o caso .5auricio. puede compartir su clave pblica con .6oracio. y guardar celosamente la privada+ Encriptando datos !/ora supongamos que el profesor =6oracio> desea mandarle un mensa#e a =5auricio>? lo nico que tendr que /acer es consultar la clave pblica de =5auricio>, dividir el mensa#e que quiere enviarle, asignarle un alfabeto num,rico a cada tro0o y calcular para cada divisin: c*n e mod n Desencriptando $on el mensa#e que le /a llegado a =5auricio>, lo que tiene que /acer es dividirlo y usar su clave privada para calcular: n*c d mod n Implementar el algoritmo RSA en Java 6e dividido el programa en dos clases: la primera mane#a toda la lgica del algoritmo R!, mientras que la segunda es simplemente la que muestra los resultados+ ! continuacin colocar, la totalidad del cdigo fuente del programa /ec/o en Java+ Luego explicar, paso a paso lo que considere importante y9o interesante+ -rimera clase. %&'.ava /+ * RSA.java * * Creado 24 de octubre de 2007, 12:02 PM * */ import java.math.BigInteger; import java.util.*; import java.io.*; /** * * @author Casidiablo */ public class RSA { int tamPrimo; BigInteger n, q, p; BigInteger totient; BigInteger e, d; /** Constructor de la clase RSA */ public RSA(int tamPrimo) { this.tamPrimo tamPrimo; generaPrimo!(); //e!era " # $ genera"lave!(); //e!era e # d #
public void generaPrimo!() { p new BigInteger(tamPrimo, $%, new Random()); do q new BigInteger(tamPrimo, $%, new Random()); while(q.&ompare'o(p)%); #
public void genera"lave!() { // ! % " * $ n p.multipl((q); // toltie!t % &"'1(*&$'1( totient p.!u)tra&t(BigInteger.value*+($)); totient totient.multipl((q.!u)tra&t(BigInteger.value*+($))); // )le*i+os u! e co"ri+o de # +e!or $ue ! do e new BigInteger(, * tamPrimo, new Random()); while((e.&ompare'o(totient) - .$) // (e.g&d(totient).&ompare'o(BigInteger.value*+($)) - %)); // d % e,1 +od totie!t d e.modInver!e(totient); #
/** * Encripta el texto usando la clave pblica * * @param +e!saje Ristra $ue co!tie!e el +e!saje a e!cri"tar * @return )l +e!saje ci-rado co+o u! vector de .i*/!te*ers */ public BigInteger01 en&ripta(String men!aje) { int i; )(te01 temp new )(te0$1; )(te01 digito! men!aje.getB(te!(); BigInteger01 )igdigito! new BigInteger0digito!.length1;
!or(i%; i2)igdigito!.length;i33){ temp0%1 digito!0i1; )igdigito!0i1 new BigInteger(temp); #
BigInteger01 en&riptado new BigInteger0)igdigito!.length1;
public BigInteger damep() {return(p);# public BigInteger dameq() {return(q);# public BigInteger dametotient() {return(totient);# public BigInteger damen() {return(n);# public BigInteger damee() {return(e);# public BigInteger damed() {return(d); # $a segunda clase (que contiene el mtodo main).0ain.ava import java.io.*; import java.math.BigInteger; /** * * @author Casidiablo */ public class 6ain {
# Cosas interesantes por notar Lo primero es ver que usamos una clase del paquete #ava+mat/: 2ig&nteger+ "sta clase escrita por Jos/ 2loc/ y 5ic/ael 5c$los4ey, que nos permitir /acer operaciones con nmeros enteros demasiado grandes, y nos provee funciones anlogas a todos los operadores primitivos de enteros+ @e auq mismo es interesante resaltar las funciones: compare:o , subtract, multiply, gcd , mod%o), mod&nverse que sirven para comparar, restar, multiplicar, comn divisor, mdulo del exponente, y el mdulo del exponente inverso, respectivamente+ !dems la funcin totring7int8, que convertir el valor de un ob#eto 2ig&nteger, a su valor equivalente a la representacin String de este 2ig&nteger en la ra0 dada+ * posteriormente, ya siendo un ob#eto tring lo que se mane#a, se usa la funcin toApper$ase para convertir el texto en maysculas+ "n el m,todo genera%rimos de la clase R!+#ava, generamos los primos p y q+ ro!ando el programa %ara e#ecutar el programa e#ecutaremos el comando: #ava 5ain tamanio%rimo, por e#emplo encriptemos la frase =6ello parce> en ;'B bits: java 6ain $,A 'am "lave9 0$,A1 p9 0"B$%$<$B;<CC,B;DB,E$"CA<;E%$%C$D1 q9 0F"AG<G;,BEBDCC$B<,C<D,GCG,A>,DBB1 "lave pu)li&a (n,e) n9 0BBA,FEB$FF%BECBG,F,>B,A>"A;E",CB"%BDCC<E<BF,B$DE<AA%";%BBA$BA,,G1 e9 0<FE<A<BG"$,"%C;"F<BC;ECBG;<C%D$ED>$DF$D%A%D$$;EB<AABA;G"$,G>BA%$1 "lave pu)li&a (n,d) n9 0BBA,FEB$FF%BECBG,F,>B,A>"A;E",CB"%BDCC<E<BF,B$DE<AA%";%BBA$BA,,G1 d9 0E%B%$%G$BAC">EGD%E$,AFD$>,CFG$,B;ACC%<G,$%D>EFC<BA;,;GE"A,C>G$,$1 'e8to a en&riptar9 hello par&e- 'e8to en&riptado9 0 B"FDA<G$<;GDA,<BF,FBEG;$;AGADACG",BBCBA<DGB>D"<B>FB%>FFB;GCF$B,B <",D%BBB%B<ED%A,"$ACBDAGG""F,;%;A>GC<$$%<FB<;,$BEBEFCBBABC"GE;BB ,DA>FC,%,G>>BB<AGG"G,<,B<"$B,BA"GG,%%A$%GEBABD"A<$;DF<DADGC,"A"B ,DA>FC,%,G>>BB<AGG"G,<,B<"$B,BA"GG,%%A$%GEBABD"A<$;DF<DADGC,"A"B ;AAA;A;A"<">A;B$B$>D<G$FFAA;$,CFBB<E%;G;"A"GA>$%B>">CD%A%%EC>GBE A$EDAGBD;G;>DA">BABBA><AAFE$>G,GACDBGAB$GE%;GCB>BCEABBB,CB,AF%"G A;$>;%$%FA"F,<BF;%A">AF<FC",%E%F$C"$"$EEA>GA<,"C,<;B"C>;A$;$DC% <DCCEEGBFG"B";F<B"%<FG;A"B"DAEAEDC<BBBAGAGAE%A<GE;;<<BEAE;B<,,$ A%;FF%FA>G,FE;EB<B"C$;;;AFA%F;;>E$G;>FFBDCD,<AF$$,EBBAECBAB%B,%, E;$G;AADB">>FBBA;$,E;,D,;<CEA;>E>;<ABBG$AFC,G<C;CG;G<B>>C$>%E$<% <",D%BBB%B<ED%A,"$ACBDAGG""F,;%;A>GC<$$%<FB<;,$BEBEFCBBABC"GE;BB $<"B,%DA,B<%""<<BGF;E$,EBFAD$$GB,GB%"AAG;G>A$C;,G%GFAE<EC>GC>B,1 'e8to de!en&ritado9 0hello par&e-1 "so es todoC Creacin de la inter"a# gr$"ica de usuario usando S%ing !/ora crearemos el front(end para usar el programa de encriptacin9desencriptacin+ * aqu me gustara tratar de mostrarles cmo crear interfaces grficas desde cero, usando la =t,cnica> que yo uso+ "sto puede parecer muy tonto para algunos, pero en verdad son muc/os los casos en los que /e visto a las personas de mi universidad maldici,ndo por no poder crear una bendita DA&+ %or esto, me gustara enfati0ar en la creacin de DA&s+ Lo primero es imaginarse como podra ser el dise-o+++ poner la mente a traba#ar, coger papel y lpi0 y comen0ar a dise-ar+ Lo primero que se me ocurre es algo como esto: Lo primero que salta a la vista es que: como artista me muero de /ambre, y como editor de grficos digitales: peor+ %ero /asta aqu lo importante es tener claro qu, se va a /acer+ Ana ve0 escogemos cual de los dos dise-os vamos a usar 7prefiero el segundo8, a programar se di#oC :en en cuenta que como vamos a usar )ing, debemos importar el paquete #avax+s)ing+ !/ora, lo primero es crear la ventana que contendr nuestro programa, para lo cual utili0aremos un ob#eto JErame+ * comen0ar a pensar cmo se van a distribuir los ob#etos dentro de la misma, para lo cual se /ace uso de los =layouts>+++ tenemos muc/as opciones, de las cuales me gustara comentarles las ms importantes y luego decidiremos cual es la ms adecuada: "s posible crear los ob#etos de la interfa0 de usuario, y asignarles coordenadas y tama-os especficos dentro de la ventana 7/a0lo solo cuando sea verdaderamente necesario8+ "s posible usar DridLayout, que nos permitir mane#ar el contenido de la ventana como si fuera una tabla de F por * celdas+ @entro de cada celda colocaramos un ob#eto de la DA&+ Gtra opcin es usar 2orderLayout, que nos permite distribuir los ob#etos en cinco espacios: norte, sur, este, oeste y centro, siendo este ltimo el ms grande de todos+ Lo primero es ver qu, coincidencias existen entre las posiciones de los ob#etos, y lo diagramamos de nuevo en papel: $omo podemos ver, en el rea ms grande 7la de aba#o, en verde8 /ay dos reas de texto que ocupan el mismo tama-o+++ as que una buena opcin sera meterlas en un DridLayout que tenga una fila y dos columnas+ !rriba 7en ro#o8, aunque no es la me#or interpretacin que /e /ec/o 7la cuestin es que quede lo ms sencillo posible8, podemos observar que /ay una cuadrcula de dos filas por tres columnas+ !s que lo ms conveniente es usar dos contenedores que usen DridLayout+ Ano para arriba, y el otro para aba#o 7Ho para el centroI8+ * al JErame, asignar el layout 2orderLayout, situando dic/os contenedores en 12%34 y "E13E% 7se ve un poco me#or que en la /o#a, pero solo un poco+++ al fin y al cabo no me /aba quedado tan feo8. Lo que en dividi,ndolo mentalmente sera: !dems de esto, tenemos que decidir como vamos a mane#ar los eventos de la DA&, es decir, qu, /acer cuando el usuario le d, clic en el botn =Denerar $laves> o en el boitn de radio ="ncriptar>, y para ello me gustara ense-arles en este mismo programa J difirentes tipos de usar eventos: @esde una clase interna annima @esde una clase interna @esde un m,todo dentro de la clase %ero vamos por partes+++ $on el fin de que entendamos y aprendamos de una manera ms sencilla, explicar, parte por parte la clase 5entana%&'.ava, comencemos con la importacin de paquetes y la declaracin de la misma: import java8.!4ing.*; import java.a4t.*; import java.a4t.event.*; import java.math.BigInteger; public class 5entanaRSA extends %&rame implements Action'istener{ 1o /ay muc/o que explicar aqu: importamos los paquetes para interfaces grficas )ing y !3:, adems del paquete que contiene las clases para mane#ar eventos y la clase 2ig&nteger+ !l declarar la clase 7como va a ser una ventana8 /eredamos de la clase JErame e implementamos la interfa0 !ctionListener para mane#ar eventos+ !/ora declaramos los ob#etos que usaremos, y posteriormente los iniciaremos en el constructor: private %(ext&ield &aja'amPrimo; private %Button )tnHenenerar"lave!; private Button)roup grupoBotone!*p&ion; private %RadioButton )tnFn&riptar, )tnGe!Fn&riptar; private %(extArea area*rigen, areaGe!tino; private Container &ntArea!, &ntHen"lave!; private RSA r!a; private BigInteger01 te8to"i+rado; "n el constructor de la clase vamos a iniciar los ob#etos con sus respectivos valores, adems de asignarle un mane#ador de eventos a cada ob#eto de la interfa0 grfica: public 5entanaRSA() { super(7Inter+aI Hra+i&a . RSA7);
&aja'amPrimo new %(ext&ield(); &aja'amPrimo.addA&tion@i!tener( new Action'istener() { public void a&tionPer+ormed(ActionEvent evt) { generar"lave!(); # #);
)tnHenenerar"lave! new %Button(7Henerar "lave!7); )tnHenenerar"lave!.addA&tion@i!tener(this);
)tnFn&riptar new %RadioButton(7Fn&riptar7, !alse); )tnFn&riptar.addA&tion@i!tener( new 6anejadorBoton*p&ion() ); )tnFn&riptar.!etFna)led(!alse); )tnGe!Fn&riptar new %RadioButton(7Ge!en&riptar7, !alse); )tnGe!Fn&riptar.addA&tion@i!tener( new 6anejadorBoton*p&ion() ); )tnGe!Fn&riptar.!etFna)led(!alse);
grupoBotone!*p&ion new Button)roup(); grupoBotone!*p&ion.add()tnFn&riptar); grupoBotone!*p&ion.add()tnGe!Fn&riptar);
area*rigen new %(extArea(); area*rigen.!etJrapSt(leJord(true); area*rigen.!et@ineJrap(true); areaGe!tino new %(extArea(); areaGe!tino.!et@ineJrap(true); areaGe!tino.!etFdita)le(!alse);
&ntArea! new Container(); &ntHen"lave! new Container();
&ntHen"lave!.!et@a(out(new )rid'a$out(,,B)); &ntHen"lave!.add(new %'abel(7Gigita el tama:o del nKmero primo9 7)); &ntHen"lave!.add(&aja'amPrimo); &ntHen"lave!.add()tnHenenerar"lave!); &ntHen"lave!.add(new %'abel(7Gigita el te8to a &i+arLde!&i+rar97)); &ntHen"lave!.add()tnFn&riptar); &ntHen"lave!.add()tnGe!Fn&riptar);
!etSiIe(>;%,B%%); !et5i!i)le(true); # %aso a explicar lo ms importante: "l m,todo super sirve para iniciar el ob#eto del cual /ereda una clase y en este caso, que redamos de JErame, le enviamos el texto que va a tener la barra del ttulo de la ventana+ $on el m,todo get"ontentPane, asignamos a la ventana el layout que administrar su contenido+++ en este caso un Border'a$out+ 6e aqu una parte interesante, vamos a definir el primer mane#ador de eventos usando una clase inrterna an6nima+ "sta se la asignamos al ob#eto &aja'amPrimo, y nos permitir mane#ar los eventos que genere dic/o ob#eto 7en este caso el evento es que se de "nter despues de escribir algo sobre esta ca#a de texto8+ Lo primero es usar el m,todo addA&tion@i!tener para adicionar un mane#ador de eventos+ "ste m,todo recibe un ob#eto que /aya implementado la interfa0 Action'istener, que mane#ar los eventos+ Ei#,monos que creamos una clase de tipo Action'istener, y por ende debemos redeclarar el m,todo a&tionPer+ormed, el cual ser invocado al producirse un evento+ "n este caso, cuando alguien escriba algo sobre la ca#a de texto y presione "nter, se invocar el m,todo generar"lave!()+ !/ora utili0aremos otra t,cnica para mane#ar eventos: se trata de que, como en este caso, la clase principal 75entana%&'.ava8 implemente la interfa0 Action'istener, y dic/a clase mane#e eventos+ :e recuerdo que al implementar la interfa0 Action'istener, una clase est obligada a declarar el m,todo a&tionPer+ormed, vaya o no a usarlo+ "sta ve0 vamos a asociar este mane#ador de eventos al botn =Denerar claves> 7)tnHenenerar"lave!8, usando el m,todo addA&tion@i!tener as: bt!e!e!erarClaves.addActio!5iste!er&this(+ $abe notar aqu, que usamos la palabra this, para indicar al m,todo addActio!5iste!er, que el mane#ador de eventos del botn bt!e!e!erarClaves,ser la misma clase donde este se encuentra+ 6ora de usar la tercera t,cnica de mane#o de eventos+++ esta ve0 se trata de usar una clase interna, en donde se implementar alguna interfa0 de mane#o de eventos 7en este caso la ya mencionada Action'istener8+++ esta t,cnica la vamos a usar para manipular los eventos generados por los botones de radio, y su uso es muy sencillo: basta con crear un ob#eto de la clase dentro del m,todo addA&tion@i!tener as: )tnFn&riptar.addA&tion@i!tener( new 6anejadorBoton*p&ion() ); 5s adelante veremos cmo est construida la clase 6anejadorBoton*p&ion $on respecto a la iniciali0acin de los otros ob#etos de la DA& no creo que /aya muc/o que explicar, pero me gustara recalcar el m,todo !etFna)led() que es bastante til+ "ste m,todo lo poseen casi todos los ob#etos de interfa0 grfica, y sirve para /abilitar9in/abilitar los ob#etos mismos+ Recibe un valor booleano, y por e#emplo cuando /acemos: )tnFn&riptar.!etFna)led(!alse);, estamos indicando que el ob#eto )tnFn&riptar va a estar in/abilitado+ "l mane#o de contenedores en muy simple+ Recordemos que usaremos dos contenedores: uno para las areas de texto de aba#o, y el otro para los ob#etos de arriba+ Los contenedores no son ms que ob#etos de la clase Container, a los que les asignamos un layout que distribuir los ob#etos que contenga+ "n nuestro caso, recordemos que el contenedor superior ser una cuadrcula de 'FJ celdas, por lo cual podremos asignar dic/o layout de la siguiente forma: &ntHen"lave!.!et@a(out(new )rid'a$out(,,B)) Ana ve0 /ayamos definido el administrador de contenido, nos dispondremos a a-adir los ob#etos de la interfa0 grfica que contendr+++ esto lo /acemos con el m,todo add, que no solo recibe ob#etos de la DA&, sino tambi,n otros contenedores: &ntHen"lave!.add(&aja'amPrimo); Gtra cosa interesante por notar es el uso de los scrolls 7%Scroll*ane8, en este caso lo usamos para envlover las areas de texto 7%(extArea8, ya que posiblemente contendrn muc/as letras y si es necesario que pueda mostrarnoslas todas+ %ara ello, al a-adir el ob#eto al contenedor 1G /acemos esto: add(area*rigen) &1G que cargamos el area dentro del scroll as: add(new %scroll*ane(area*rigen)) @e lo contrario lo ms seguro es que no podamos acceder al texto que se encuentre aba#o, cuando ya no quepa ms+ !dems de los crolls, podemos usar los m,todos !et@ineJrap y !etJrapSt(leJord, que no permitir scrolls /ori0ontales 7causados por e#emplo por palabras muy largas8+ !l momento de a-adir ob#etos al JErame, lo podemos /acer directamente invocando el m,todo get"ontentPane seguido del m,todo add+ "n este caso, como usamos el layout Border'a$out, debemos pasarle un parmetro adicional al m,todo add, que le indicar en qu, parte situar el ob#eto 7arriba, aba#o, i0quierda, derec/a o centro8, dic/o parmetro es un entero que podemos tomar de las variables pblicas estticas de la clase Border'a$out+++ por e#emplo para situar el contenedor &ntHen"lave! arriba debemos poner lo siguiente: get"ontentPane().add(&ntHen"lave!, Border'a$out.M*R'N); %or ltimo, para asignarle un tama-o a la ventana y /acerla visible 7por defecto viene invisible8, debemos usar los m,todos !etSiIe(>;%,B%%) y !et5i!i)le(true) respectivamente+ Keamos a/ora el m,todo a&tionPer+ormed, que ser invocado cada ve0 que el botn )tnHenenerar"lave! genere un evento: // +a!ejar eve!tos de bot6! public void a&tionPer+ormed( ActionEvent evento ) { i!(evento.getSour&e().equal!()tnHenenerar"lave!)) generar"lave!(); # Lo nico a resaltar aqu es el m,todo getSour&e de la clase ActionEvent, que en con#unto con el m,todo equal! de la clase #b,ect nos permitir saber quin gener el evento+ "l siguiente m,todo a tratar es generar"lave!, que simplemente invocar los m,todos generaPrimo! y genera"lave! de la clase %&'.ava, y nos los mostrar: private void generar"lave!() { i!(&aja'amPrimo.get'e8t().equal!(77)) %#ption*ane.!ho46e!!ageGialog(null, 7Mo haI introdu&ido el tama:o del primo7, 7'enemo! pro)lema!7, %#ption*ane.FRR*RO6FSSAHF); else { r!a new RSA(Integer.par!eInt(&aja'amPrimo.get'e8t())); r!a.generaPrimo!(); r!a.genera"lave!(); %(extArea area new %(extArea(,%,;%); area.!etFdita)le(!alse); area.!et@ineJrap(true); area.append(7'am &lave9 73&aja'amPrimo.get'e8t()37=n=n7); area.append(7p9073r!a.damep()371=n=nq9073r!a.dameq()371=n=n7); area.append(7"lave pu)li&a (n,e)9=n=nn9073 r!a.damen()371=n=ne9073r!a.damee()371=n=n7); area.append(7"lave pu)li&a (n,d)9=n=nn9073r!a.damen()371=n=nd907 3r!a.damed()3717); %#ption*ane.!ho46e!!ageGialog(null, new %scroll*ane(area), 7Primo! generado!7, %#ption*ane.IMD*R6A'I*MO6FSSAHF); )tnFn&riptar.!etFna)led(true); )tnGe!Fn&riptar.!etFna)led(true); # # @e aqu podemos tomar algunas cosas interesantes+++ $omencemos con la clase %#ption*ane, la cual nos permitir usar cuadros de dilogo bsicos+ "n este caso solo usamos su m,todo esttico !ho46e!!ageGialog, en donde podremos introducir un texto a mostrar 7o un ob#eto, como veremos ,ms adelante8, el ttulo del cuadro de dilogo, y un icono a mostrar+ "n cuanto al icono, podemos escoger entre imgenes referentes a error, informacin, alarma, pregunta y creo que no ms+++ por e#emplo, para usar el de error podemos /acer %option*ane.FRR*RO6FSSAHF Gtro punto interesante de la clase %#ption*ane, es que en ve0 de texto simple podemos colocar un ob#eto grfico+++ por e#emplo podemos colocar un ob#eto %(extArea como en el cdigo de arriba: %option*ane.!ho46e!!ageGialog(null, new %scroll*ane(area),7'itulo7) %asemos entonces a ver cmo est construida la clase interna , que en nuestro caso mane#a los eventos de los botones de radio: private class 6anejadorBoton*p&ion implements Action'istener {
// +a!ejar eve!tos de bot6! de o"ci6! public void a&tionPer+ormed( ActionEvent evento ) { i!(evento.getSour&e().equal!()tnFn&riptar)) { i!(area*rigen.get'e8t().equal!(77)) %option*ane.!ho46e!!ageGialog(null, 7Mo haI introdu&ido dato! para &i+rar7, 7'enemo! pro)lema!7, %#ption*ane.FRR*RO6FSSAHF); else { te8to"i+rado r!a.en&ripta(area*rigen.get'e8t()); areaGe!tino.!et'e8t(77); !or(int i%; i2te8to"i+rado.length; i33) areaGe!tino.append(te8to"i+rado0i1.toString()); # # else i!(evento.getSour&e().equal!()tnGe!Fn&riptar)) { i!(area*rigen.get'e8t().equal!(77)) %option*ane.!ho46e!!ageGialog(null, 7Mo haI introdu&ido dato! para de&i+rar7, 7'enemo! pro)lema!7, %#ption*ane.FRR*RO6FSSAHF); else { areaGe!tino.!et'e8t(77); String re&uperar'e8toPlano r!a.de!en&ripta(te8to"i+rado); areaGe!tino.!et'e8t(re&uperar'e8toPlano); # # #
# $omo puedes ver implementa la interfa0 Action'istener, por lo que ms aba#o tiene que declarar el m,todo a&tionPer+ormed+ !ll adentro se cifran9decifran lo que se /aya puesto en una de las areas de texto+ La verdad no /ay muc/o que explicar aqu as que vamos directamente al cdigo del m,todo main: public !tati& void main(String arg!01) { %&rame.!etGe+ault@ooPAndDeelGe&orated(true); 5entanaRSA ventana new 5entanaRSA(); ventana.!etGe+ault"lo!e*peration(%&rame.FQI'O*MO"@*SF); # !qu solo /ay dos cosas por resaltar: %&rame.!etGe+ault@ooPAndDeelGe&orated(true): esto lo que /ace es activar el Loo4LEeel, y logramos que nuestra ventana se vea bonita y adems que se muestre igual en cualquier sistema operativo+ ventana.!etGe+ault"lo!e*peration(%&rame.FQI'O*MO"@*SF): esto nos evita tener que poner a la escuc/a algn m,todo para cerrar la ventana, es decir, con esto le decimos que cuando el usuario de clic en la F de la esquina superior derec/a, se cierre el programa+ @e otro modo /ay que usar otros m,todos muc/o ms complicados+ 2ien, eso es todo+++ probemos entonces el programaC i no colocamos ningn texto para cifrar9decifrar: Ammm, a/ora que miro la anterior imgen+++ Hse escribe =/as> o =/a0>I "n fin+++ pasemos a la encriptacin: * la desencriptacin 7Ho desencripcinI8 $omo puedes ver+++ /ubo un problema con las tildes y los smbolos netamente castellanos, pero culpa de Java lo #uro:7 Cdigo "uente !/ora s les pongo el cdigo fuente completo, para que puedan estudiarlo ms fcil, no sin antes recordarles que est ba#o la licencia D%L y que pueden copiarlo, modificarlo y distribuirlo librementeC /* * 7e!ta!aRSA.java * * Creado 28 de octubre de 2007, 04:00 PM * */ import java8.!4ing.*; import java.a4t.*; import java.a4t.event.*; import java.math.BigInteger; /** * * @author Casidiablo */ public class 5entanaRSA extends %&rame implements Action'istener{
&aja'amPrimo new %(ext&ield(); &aja'amPrimo.addA&tion@i!tener( new Action'istener() { public void a&tionPer+ormed(ActionEvent evt) { generar"lave!(); # #);
)tnHenenerar"lave! new %Button(7Henerar "lave!7); )tnHenenerar"lave!.addA&tion@i!tener(this);
)tnFn&riptar new %RadioButton(7Fn&riptar7, !alse); )tnFn&riptar.addA&tion@i!tener( new 6anejadorBoton*p&ion() ); )tnFn&riptar.!etFna)led(!alse); )tnGe!Fn&riptar new %RadioButton(7Ge!en&riptar7, !alse); )tnGe!Fn&riptar.addA&tion@i!tener( new 6anejadorBoton*p&ion() ); )tnGe!Fn&riptar.!etFna)led(!alse);
grupoBotone!*p&ion new Button)roup(); grupoBotone!*p&ion.add()tnFn&riptar); grupoBotone!*p&ion.add()tnGe!Fn&riptar);
area*rigen new %(extArea(); area*rigen.!etJrapSt(leJord(true); area*rigen.!et@ineJrap(true); areaGe!tino new %(extArea(); areaGe!tino.!et@ineJrap(true); areaGe!tino.!etFdita)le(!alse);
&ntArea! new Container(); &ntHen"lave! new Container();
&ntHen"lave!.!et@a(out(new )rid'a$out(,,B)); &ntHen"lave!.add(new %'abel(7Gigita el tama:o del nKmero primo9 7)); &ntHen"lave!.add(&aja'amPrimo); &ntHen"lave!.add()tnHenenerar"lave!); &ntHen"lave!.add(new %'abel(7Gigita el te8to a &i+arLde!&i+rar97)); &ntHen"lave!.add()tnFn&riptar); &ntHen"lave!.add()tnGe!Fn&riptar);
// +a!ejar eve!tos de bot6! public void a&tionPer+ormed( ActionEvent evento ) { i!(evento.getSour&e().equal!()tnHenenerar"lave!)) generar"lave!(); #
//e!erar claves private void generar"lave!() { i!(&aja'amPrimo.get'e8t().equal!(77)) %#ption*ane.!ho46e!!ageGialog(null,7Mo haI introdu&ido el tama:o del primo7, 7'enemo! pro)lema!7, %#ption*ane.FRR*RO6FSSAHF); else { r!a new RSA(Integer.par!eInt(&aja'amPrimo.get'e8t())); r!a.generaPrimo!(); r!a.genera"lave!(); %(extArea area new %(extArea(,%,;%); area.!etFdita)le(!alse); area.!et@ineJrap(true); area.append(7'am &lave9 73&aja'amPrimo.get'e8t()37=n=n7); area.append(7p9073r!a.damep()371=n=nq9073r!a.dameq()371=n=n7); area.append(7"lave pu)li&a (n,e)9=n=nn9073r!a.damen()371=n=ne9073r!a.damee()371=n=n7); area.append(7"lave pu)li&a (n,d)9=n=nn9073r!a.damen()371=n=nd9073r!a.damed()3717); %#ption*ane.!ho46e!!ageGialog(null, new %Scroll*ane(area),7Primo! generado!7, %#ption*ane.IMD*R6A'I*MO6FSSAHF); )tnFn&riptar.!etFna)led(true); )tnGe!Fn&riptar.!etFna)led(true); # #
// clase i!ter!a "rivada "ara +a!ejar eve!tos de bot6! de o"ci6! private class 6anejadorBoton*p&ion implements Action'istener {
// +a!ejar eve!tos de bot6! de o"ci6! public void a&tionPer+ormed( ActionEvent evento ) { i!(evento.getSour&e().equal!()tnFn&riptar)) { i!(area*rigen.get'e8t().equal!(77)) %#ption*ane.!ho46e!!ageGialog(null,7Mo haI introdu&ido dato! para &i+rar7, 7'enemo! pro)lema!7, %#ption*ane.FRR*RO6FSSAHF); else { te8to"i+rado r!a.en&ripta(area*rigen.get'e8t()); areaGe!tino.!et'e8t(77); !or(int i%; i2te8to"i+rado.length; i33) areaGe!tino.append(te8to"i+rado0i1.toString()); # # else i!(evento.getSour&e().equal!()tnGe!Fn&riptar)) { i!(area*rigen.get'e8t().equal!(77)) %#ption*ane.!ho46e!!ageGialog(null,7Mo haI introdu&ido dato! para de&i+rar7, 7'enemo! pro)lema!7, %#ption*ane.FRR*RO6FSSAHF); else { areaGe!tino.!et'e8t(77); String re&uperar'e8toPlano r!a.de!en&ripta(te8to"i+rado); areaGe!tino.!et'e8t(re&uperar'e8toPlano); # # #
# // -i! de la clase i!ter!a "rivada Ma!ejador.oto!9"cio!*/
public !tati& void main(String arg!01) { %&rame.!etGe+ault@ooPAndDeelGe&orated(true); 5entanaRSA ventana new 5entanaRSA(); ventana.!etGe+ault"lo!e*peration(%&rame.FQI'O*MO"@*SF); # # /* * RSA.java * * Creado 24 de octubre de 2007, 12:02 PM * */ import java.math.BigInteger; import java.util.*; import java.io.*; /** * * @author Casidiablo */ public class RSA { int tamPrimo; BigInteger n, q, p; BigInteger totient; BigInteger e, d; /** Constructor de la clase RSA */ public RSA(int tamPrimo) { this.tamPrimo tamPrimo; #
public void generaPrimo!() { p new BigInteger(tamPrimo, $%, new Random()); do q new BigInteger(tamPrimo, $%, new Random()); while(q.&ompare'o(p)%); #
public void genera"lave!() { // ! % " * $ n p.multipl((q); // toltie!t % &"'1(*&$'1( totient p.!u)tra&t(BigInteger.value*+($)); totient totient.multipl((q.!u)tra&t(BigInteger.value*+($))); // )le*i+os u! e co"ri+o de # +e!or $ue ! do e new BigInteger(, * tamPrimo, new Random()); while((e.&ompare'o(totient) - .$) // (e.g&d(totient).&ompare'o(BigInteger.value*+($)) - %)); // d % e,1 +od totie!t d e.modInver!e(totient); #
/** * Encripta el texto usando la clave pblica * * @param +e!saje Ristra $ue co!tie!e el +e!saje a e!cri"tar * @return )l +e!saje ci-rado co+o u! vector de .i*/!te*ers */ public BigInteger01 en&ripta(String men!aje) { int i; )(te01 temp new )(te0$1; )(te01 digito! men!aje.getB(te!(); BigInteger01 )igdigito! new BigInteger0digito!.length1;
!or(i%; i2)igdigito!.length;i33){ temp0%1 digito!0i1; )igdigito!0i1 new BigInteger(temp); #
BigInteger01 en&riptado new BigInteger0)igdigito!.length1;
public BigInteger damep() {return(p);# public BigInteger dameq() {return(q);# public BigInteger dametotient() {return(totient);# public BigInteger damen() {return(n);# public BigInteger damee() {return(e);# public BigInteger damed() {return(d);# # "opyleft 7 "ristian "astiblanco 8))9 El contenido de esta obra est: bao la $icencia de documentaci6n libre ;1U (;<=$) 5ersi6n (.8 o cualquier otra versi6n posterior publicada por la <ree &oft>are <oundation. &e otorga permiso para copiar, distribuir y/o modificar el contenido de este documento bao los trminos de dic!a licencia, e?ceptuando obviamente, los contenidos tem:ticos, im:genes, etc., que pertenezcan a otros autores, y para los cuales se aplica la licencia deteterminada por los mismos.