Está en la página 1de 20

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;

!or(i%; i2)igdigito!.length; i33)
en&riptado0i1 )igdigito!0i1.modPo4(e,n);

return(en&riptado);
#

/**
* "esencripta el texto ci!rado usando la clave privada
*
* @param e!cri"tado Arra# de objetos .i*/!te*er $ue co!tie!e el te0to ci-rado
* $ue ser1 dese!cri"tado
* @return 23e decr#"ted "lai!te0t
*/
public String de!en&ripta(BigInteger01 en&riptado) {
BigInteger01 de!en&riptado new BigInteger0en&riptado.length1;

!or(int i%; i2de!en&riptado.length; i33)
de!en&riptado0i1 en&riptado0i1.modPo4(d,n);

&har01 &harArra( new &har0de!en&riptado.length1;

!or(int i%; i2&harArra(.length; i33)
&harArra(0i1 (&har) (de!en&riptado0i1.int5alue());

return(new String(&harArra());
#

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 {

/**
* @param ar*u+e!tos de la l4!ea de co+a!dos
*/
public !tati& void main(String01 arg!) throws I#Exception {
i!(arg!.length - $) {
S$stem.out.println(7Sinta8i!9 java RSA 0tama:o de lo! primo!17);
S$stem.out.println(7por ejemplo9 java RSA ;$,7);
arg! new String0$1;
arg!0%17$%,<7;
#
int tamPrimo Integer.par!eInt(arg!0%1);
RSA r!a new RSA(tamPrimo);
S$stem.out.println(7'am "lave9 073 tamPrimo 3 71=n7);
S$stem.out.println(7p9 07 3 r!a.damep().toString($>).to?pper"a!e() 3 717);
S$stem.out.println(7q9 07 3 r!a.dameq().toString($>).to?pper"a!e() 3 71=n7);
S$stem.out.println(7"lave pu)li&a (n,e)7);
S$stem.out.println(7n9 07 3 r!a.damen().toString($>).to?pper"a!e() 3 717);
S$stem.out.println(7e9 07 3 r!a.damee().toString($>).to?pper"a!e() 3 71=n7);
S$stem.out.println(7"lave pu)li&a (n,d)7);
S$stem.out.println(7n9 07 3 r!a.damen().toString($>).to?pper"a!e() 3 717);
S$stem.out.println(7d9 07 3 r!a.damed().toString($>).to?pper"a!e() 3 71=n7);
S$stem.out.println(7'e8to a en&riptar9 7);
String te8toPlano ( new Bu!!eredReader(new
InputStreamReader(S$stem.in))).read@ine();

BigInteger01 te8to"i+rado r!a.en&ripta(te8toPlano);

S$stem.out.println(7=n'e8to en&riptado9 07);
!or(int i%; i2te8to"i+rado.length; i33) {
S$stem.out.print(te8to"i+rado0i1.toString($>).to?pper"a!e());
i!(i - te8to"i+rado.length.$)
S$stem.out.println(77);
#
S$stem.out.println(71=n7);

String re&uperar'e8toPlano r!a.de!en&ripta(te8to"i+rado);
S$stem.out.println(7'e8to de!en&ritado9 073 re&uperar'e8toPlano 3717);
#

#
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);

get"ontentPane().!et@a(out(new Border'a$out(B,B));

&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);

&ntArea!.!et@a(out(new )rid'a$out($,,,;,;));
&ntArea!.add(new %Scroll*ane(area*rigen));
&ntArea!.add(new %Scroll*ane(areaGe!tino));

get"ontentPane().add(&ntHen"lave!, Border'a$out.M*R'N);
get"ontentPane().add(&ntArea!, Border'a$out."FM'FR);

!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{

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;
/** Constructor de la clase -entanaRSA */
public 5entanaRSA() {
super(7Inter+aI Hra+i&a . RSA7);

get"ontentPane().!et@a(out(new Border'a$out(B,B));

&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);

&ntArea!.!et@a(out(new )rid'a$out($,,,;,;));
&ntArea!.add(new %Scroll*ane(area*rigen));
&ntArea!.add(new %Scroll*ane(areaGe!tino));

get"ontentPane().add(&ntHen"lave!, Border'a$out.M*R'N);
get"ontentPane().add(&ntArea!, Border'a$out."FM'FR);

!etSiIe(>;%,B%%);
!et5i!i)le(true);
#

// +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;

!or(i%; i2)igdigito!.length; i33)
en&riptado0i1 )igdigito!0i1.modPo4(e,n);

return(en&riptado);
#

/**
* "esencripta el texto ci!rado usando la clave privada
*
* @param e!cri"tado Arra# de objetos .i*/!te*er $ue co!tie!e el te0to ci-rado
$ue ser1 dese!cri"tado
* @return 23e decr#"ted "lai!te0t
*/
public String de!en&ripta(BigInteger01 en&riptado) {
BigInteger01 de!en&riptado new BigInteger0en&riptado.length1;

!or(int i%; i2de!en&riptado.length; i33)
de!en&riptado0i1 en&riptado0i1.modPo4(d,n);

&har01 &harArra( new &har0de!en&riptado.length1;

!or(int i%; i2&harArra(.length; i33)
&harArra(0i1 (&har) (de!en&riptado0i1.int5alue());

return(new String(&harArra());
#

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.

También podría gustarte