Algoritmos de cifrado y descifrado RSA e IDEA para Java de alta puntuación
Encontrar dos números primos p y q
Sea n=p*q
T=( p-1 )*(q-1)
Para tomar cualquier número e, debe satisfacer e
Tome d*e%t==1
De esta manera, finalmente obtenga tres números: n d e
Deje que el mensaje sea m (m
Establezca c=(M**d)%n para obtener el mensaje cifrado c.
Establezca m=(c**e)%n y luego m == M, completando así el descifrado de c.
Nota: * * representa potencia, y D y E en el. Las dos fórmulas anteriores pueden interactuar entre sí. Cambiar
En cifrado simétrico:
N d dos números forman una clave pública, que se puede comunicar a otros
<; p>Dos números n e forman una clave privada, e se la guarda para usted y no deja que nadie lo sepa.La información enviada a otros está cifrada por e. prueba que la información fue enviada por usted, lo que constituye un mecanismo de firma
Cuando otros le envían información, utilizan el cifrado D, de modo que solo usted que tiene E puede descifrarlo
<. p>La seguridad de rsa es que no existe una forma eficaz de descomponer un número grande n.Por lo tanto, e no se puede obtener cuando se conoce n d y también es imposible encontrar d cuando se conoce n e.
& ltSecond>Práctica.
A continuación, practiquemos y veamos la operación real:
Encontrar dos números primos:
p= 47
q=59
Así
n=p*q=2773
t=(p-1)*( q-1)=2668 p>
Establezca e=63 para satisfacer e
Usando el método exhaustivo simple de Perl, puede obtener el número D con el principal completo e*d%t == 1:
c:\ Temp & gt; perl -e "foreach $i (1..9999){ print $ I, último si $i*63%2668==1 } "
847
Es decir, d = 847.
Finalmente, obtuvimos la clave
n=2773
d =847
e=63
Recibe el mensaje M=244, echemos un vistazo
Cifrado:
c=M** d%n = 244**847. %2773
Utilice el cálculo de números grandes de Perl para calcular:
c:\ Temp & gt; * 847% 2773 "
465
Es decir, después de cifrar M con D, se obtiene la información cifrada C = 465.
Descifrado:
Podemos usar E para descifrar el C cifrado y restaurar M:
m=c**e%n=465**63% 2773:
c:\ Temp>perl -Mbigint -e "Print 465**63%2773"
244
Es decir, C se descifra mediante E, obtenga m = 244, que es igual a la información original m.
& ltThird>Cifrado de cadenas
Al integrar el proceso anterior, podemos implementar un ejemplo de cifrado y descifrado de una cadena.
Cada vez, el valor ascii de un carácter en la cadena se toma como m para el cálculo y la salida se cifra con 16.
Un número en forma de cadena, representado por 3 bytes, como por ejemplo 01F.
El código es el siguiente:
#!/usr/bin/perl -w
#Programa de prueba escrito por el plan de aprendizaje del proceso de cálculo RSA p>
#水云2003-8-12
<#
Usar estrictamente;
Usar Math::BigInt;
Mi % RSA _ CORE = (n = > 2773, e= >63, d = & gt847, q=59
mi $ N = new Math::BigInt(); $ RSA _ CORE { N });
mi $ E = nueva Matemática::BigInt($ RSA _ CORE { E });
mi $ D = nueva Matemática:: BigInt ($RSA_CORE {D});
Imprimir "N = $N D = $D E = $E\N";
Sub RSA_ENCRYPT
{
Mi $r_mess = shift@_
mi ($c, $i, $M, $c, $cmess
for ($I =); 0; $i & lt longitud($$r_mess);$i++)
{
$c=ord(substr($$r_mess,$i , 1));
$M = Matemáticas::BigInt->new($c);
$C = $M->copia(); $N);
$C = sprintf "%03X", $C
$cmess. = $c;
}
return \$cmess
}
niño RSA_DECRYPT
{ p>
Mi $r_mess = shift@_
mi ($c, $i, $M, $c, $dmess);
for($ I = 0 ; $i<length($$r_mess);$i+=3)
{
$c=substr($$r_mess,$i,3 );
$ c = Hexadecimal($c);
$ M = Math::BigInt->new($c);
$C = $M->copia() ;$C->bmodpow($E,$N);
$C = chr($C);
$dmess.
= $c;
}
return \ $dmess
}
Mi $mess="RSA bebé jajaja~~ ";
$mess = $ARGV[0]if @argv>= 1;
Imprimir "cadena original:", $mess, "\n";
mi $r_cmess = RSA_ENCRYPT(\$mess);
Imprimir "cadena cifrada:", $$r_cmess, "\n";
mi $r_dmess = RSA _ DECRYPT($ r _ cmess);
Imprimir "Cadena descifrada:", $$r_dmess, " \ n ";
# EOF
Pruébalo:
c:\Temp>perl rsa-test.pl
N=2773 D=847 E=63
Cadena original: RSA baby jajaja~ ~ ~
Cadena cifrada: 5 CB 6 CD 6 BC 58 a 7709470 a 70 aa 0 aa 70 a 6 c 70 a 46 c 70 a 46 c 70 a 46 c 70 a 46 c 70 a 4.
Cadena descifrada: RSA baby jajaja~ ~ ~
c:\ Temp> Perl rsa-test.pl Enfoque de seguridad
N=2773 D =847 E =63
Cadena original: enfoque de seguridad (xfocus)
Cadena cifrada: 3393 EC 12f 0a 466 e0aa 9510d 025d 7 ba 0712 DC 379 f 47d 51c 325d 67 b.
Descifrar cadena: enfoque de seguridad (xfocus)
& lt4th>Agregar nota
Como se mencionó anteriormente, la seguridad de rsa proviene de que n es lo suficientemente grande y el n utilizado en nuestra prueba es muy pequeño, lo que no puede garantizar la seguridad en absoluto.
Podemos obtener suficiente n y D E mediante herramientas como RSAKit y RSATool.
Con esta herramienta obtenemos N y D E de 1024 bits para probar:
n = 0x 328 c 74784 df 31119c 526d 18098 e bebb 943 b 0032 b 599 ce e13c C2 BCE 7 b 5 fcd 15f 90 b 66 EC 3 a 85 f 5005d
BDC ded 9 BDF CB 3c 4 c 265 af 164 ad 55884d 8278 f 791 c 7 a 6 BF dad 55 EDB C4 f 017 f 9 CCF 1538 d4c 2013433 b 383 b
47d 80 EC 74 b 51276 ca 05 b 5d 6346 b 9 ee 5 ad 2d 7 be 7 abfb 36 e 37108 DD 60438941 D2 ed 173 CCA 50 e 114705 2
BC511951
d=0x10001
e = 0xe 760 a 3804 acde 1e8e 3d 7 DC 0197 f 9 cef 6282 ef 552 e 8 cebb 7434 b 01cb 19 a9d 87 a 3106 DD 28 c 523 c 2995
4c 5d 86 b 36 e 943080 e 4919 ca 8 ce 08718c3b 0930867 a 98 f 635 EB 9 ea 9200 b 25906d 91b 80 a 47b 773 4 y 66 en adelante 2
c 4d 70 D8 b 1 c 69 c 50 a 9d 8 B4 b 7 a3 c 9 ee 05 fff3 a 16 AFC 023731d 80634763 da 1 dcab e 9861a 4789 BD 782 a 592d 2 b
1965
Establecer información original
m = 0x 11111111111112222222222223333333333
El cálculo de un número tan grande se basa en la biblioteca de operaciones de números grandes, y el cálculo con perl es muy simple:
a) Utilice d para cifrar m, de la siguiente manera:
c=M**d%n:
c:\ Temp>perl- mbi gint -e " $ 032 b 599 CEE 13c 2 BCE 7 b 5 f
CD 15 f 90 b 66 EC 3 a 85 f 5005 dbdcded 9 BDF CB 3c 4 c 265 af 164 ad 55884d 8278 f 791 c 7 a 6 BF dad 55 EDB C4 f 0 p>
17 F9 CCF 1538 d4c 2013433 b 383 b47 d 80 EC 74 b 51276 ca 05 b 5d 6346 b 9 ee 5 ad 2d 7 be 7 abfb 36 e 37108 DD 6
0438941 D2 ed 173 CCA 50 e 114705d 7 e2bc 511951);print$x->as_hex "
0x 17b
287 be 418c 69 ECD 7c 39227 ab 681ac 422 FCC 84 bb 35 D8 a 632543 b 304 de 288 A8 d 4434 b 73d 2576 BD
45692 b 007 F3 a2 f 7 C5 F5 aa 1d 99 ef 38 66af 26 a8e 876712ed 1 D4 C4 b 293 e 26 BC 0 a 1 DC 67 e 247715 caa6b
3028 f 9461a3b 1533 EC 0 CB 476441465 f 10 D8 ad 47452 a 12db 0601c5e 8 beda 68 6 DD 96 D2 DCA 59 ea 89 b 91
f1834580c3f6d90898
Es decir, la información después de cifrar M con D es:
c = 0x 17b 287 be 418c 69 ECD 7c 39227 ab 681ac 422 FCC 84 bb 35 D8 a 632543 b 304 de 288 a8d 4434 b 73d 2576 BD
45692 b 007 F3 a2 f 7 C5 F5 aa 1d 99 ef 3866 af 26 a8e 876712ed 1 D4 C4 293 e 26 BC 0 a 1 DC 67 e 247715 caa6b
3028 f 9461a3b 1533 EC 0 CB 476441465 f 10 D8 ad 47452 a 12db 0601c5e 8 beda 686 DD 96 D2 ACD 59 ea 89 b 91
f1834580c3f6d90898
b) Utilice e para descifrar c, de la siguiente manera:
m=c**e%n:
c:\ Temp & gt ; perl-mbi gint-e " $ x = Math::BigInt-& gt; bmodpow(0x 17b 287 be 418c 69 ECD 7c 39227 ab
681ac 422 FCC 84 bb 35 D8 a 632543 b 304 de 288 a8d 4434 b 73d 2576 BD 45692 b 007 F3 a2 f 7 C5 F5 aa 1d 99 ef 3
866 af 26 a8e 876712ed 1 D4 C4 b 293 e 26 BC 0 a 1 DC 67 e 247715 caa6b 8 f 9461a3b 1533 EC 0 CB 4764414
65f 10 D8 ad 47452 a 12db 0601c5 E8 beda 686 DD 96 D2 ACD 59 ea 89 b 91f 1834580 C3 F6 d 90898, 0xE760A
804 acce 1e8e 3d 7 DC 0197 F9 cef 6282 ef 552 E8 cebb 7434 b 019 a9 d 87 a 3106 DD 28 c 523 c 29954 C5 d86b 36e 943080 e 4919ca 8 ce 08718c3b a98f 635 EB 9 unidades 9200 b 25906d 91b 80 a 4777324 e 66 aff
2c 4d 70 D8 b 1 c 69 c 50 a
9d 8 B4 b 7 a3 C9 ee 05 fff3 a 16 AFC 023731d 80634763 da 1 dcab e 9861a 4789 BD 782 a
592D2B1965, 0x 328 c 74784 df 3119c 526d 18098 e be bb 943 b 0032 b 599 CEE 13c C2 BCE 7 b 5 fcd 15f 90
b 66 EC 3 a 85 f 5005 dbdcded 9 BDF CB 3c 4 c 265 af 164 ad 55884d 8278 f 791 c 7 a 6 BF dad 55 EDB C4 f 017 f 9 CCF
1538 d4c 2013433 b 383 b47 d 80 EC 74 b 51276 ca 05 b 5d 6346 b 9 ee 5 ad 2d 7 be 7 abfb 36 e 37108 DD 60438941
d2ed 173 CCA 50 e 114705d 7 e2bc 511951); print $
Obtener E descifrado m = 0x 111111111111112222228.
La implementación habitual de RSA
RSA es simple y elegante , pero computacionalmente lento. Generalmente, RSA no se usa directamente.
La situación más común es generar aleatoriamente una clave de cifrado simétrica, luego cifrar la información usando un algoritmo de cifrado simétrico. RSA para cifrar la clave de cifrado
Finalmente, cabe señalar que se ha demostrado que N menos de 1024 bits no son seguros.
No utilice RSA con menos de 1024 bits. Lo mejor es utilizar RSA de 2048 bits.
-
Un código fuente de implementación JAVA simple del algoritmo RSA;
Nombre de archivo: RSA.java
/* p >
*Creado el 3 de marzo de 2005
*
* TODO Para cambiar la plantilla para este archivo generado, vaya a
* Ventana - Preferencias - Java - Estilo de código - Plantilla de código
*/
Importar Java .entero grande
Importar Java io .
Importar flujo de salida de Java .io;
Importar flujo de salida de archivo Java .io;
Java .io .filenotfoundexception;
Importar Java io .io excepción;
Importar Java .io . /p>
Importar Java .io .lector almacenado en búfer;
Importar tokenizador de cadena Java .
/**
* @Author Steve;
*
* TODO Para cambiar la plantilla para esta anotación de tipo generada, vaya a
* Ventana - Preferencias - Java -Estilo de código-Plantilla de código p>
*/
Clase pública RSA {
/**
*Entero grande. Cero
*/
BigInteger final estático privado CERO = BigInteger. Cero;
/**
*Entero grande. uno
*/
BigInteger final estático privado ONE = BigInteger. 1;
/**
* Pseudo BigInteger. Dos
*/
Entero grande final estático privado DOS = nuevo entero grande(" 2 ");
MyKey privado BigInteger
privado BigInteger myMod
privado int blockSize
público RSA (clave BigInteger, BigInteger n, int b) {
myKey = clave
myMod = n;
tamaño de bloque = b;
}
canal codificador vacío público (nombre de archivo de cadena){
byte [ ] bytes = nuevos bytes [tamaño de bloque/8+1];
byte[]temp
int tempLen
InputStream es = nulo p>
FileWriter escritor = nulo
Pruebe {
es = nuevo flujo de entrada de archivo (nombre de archivo
escritor = nuevo escritor de archivos (nombre de archivo +); ".
enc");
}
catch(excepción de archivo no encontrado e 1){
System.out.println("Archivo no encontrado:"+nombre de archivo );
}
catch (IOException e1){
System.out.println("Archivo no encontrado: "+ nombre de archivo +".enc" ) ;
}
/**
*Escribe el mensaje codificado en "nombre de archivo" Control Técnico
*/<. >
Prueba {
while ((tempLen = is.read(bytes, 1, tamaño de bloque/8))> 0) {
for(int I = tempLen +1;i<bytes.length;++i) {
bytes[I]= 0;
}
escritor (decodificación codificada (nuevo grande). entero(bytes))+" ");
}
}
catch (IOException e1) {
System.out. println("Error al escribir el archivo");
}
/**
*Cerrar flujo de entrada y escritura de archivos Writer
* /
Prueba {
es . close();
escritor close(); >catch (IOException e1) {
System.out.println("Error al cerrar el archivo.");
}
}
public void decodeFile(nombre de archivo de cadena){
FileReader Reader = null
OutputStream os = null
Pruebe {
reader = new FileReader(nombre de archivo);
OS = nuevo flujo de salida de archivo(filename.replace all(".enc",".dec"));
OS = nuevo flujo de salida de archivo (nombre de archivo.reemplazar todo(".enc",".dec"));
p>
}
catch(excepción de archivo no encontrado e 1){ p>
if (lector == null)
System.out.println( "Archivo no encontrado: "+nombre de archivo);
Otro
System.out.println("Archivo no encontrado: "+ nombre de archivo.replaceAll(". enc", "dec");
}
lector almacenado en búfer br = nuevo lector almacenado en búfer (lector);
int offset;
byte[] temp, toFile
StringTokenizer st = null
prueba {
mientras (br.ready()) {
ST = tokenizer de cadena nueva(br . readline());
while (st.hasMoreTokens()){
al archivo = decodificación codificada (nuevo entero grande (ST . nexttoken( ))).
toByteArray();
system . println(al archivo . length+" x "+(tamaño de bloque/8));
if(al archivo[0]= = 0 & amptoFile.length! = (tamaño de bloque/8)) {
temp = nuevos bytes [tamaño de bloque/8];
offset = temp .length-to file .
for(int I = archivo . length-1;(i<= 0)&&((I+offset)<= 0);- i ) {
temp[I+offset]= al archivo[I];
}
toFile = temp
} p>
/*if ( toFile.length!= ((blockSize / 8) + 1)){
temp = nuevo byte [(block size/8)+1];
p>system out . println(al archivo . longitud+" x "+temp . longitud);
for(int I = 1;i<temperature length;i++) {
temp[I]= al archivo. [I-1];
}
toFile = temp
}
Otros
system out . println(al archivo . length+" "+((tamaño de bloque/8)+1));*/
OS . >
}
}
catch (IOException e1) {
System.out.println( "Algo sucedió");
}
/**
*Cerrar el flujo de datos
*/
Pruebe {
SO . close();
lector .close();
}
catch (IOException e1) {
System.out .println("Error al cerrar el archivo. ");
}
}
/**
*Ejecutar & ltTT & gt; base & lt/TT & gt ;^<sup>& ltTT>pow</TT></sup>dentro de modular
* Pertenece a <TT>mod</TT& gt;
. * @param base La base a elevar
* @param pow El poder de la base
* @ param mod El dominio modular sobre el que realizar esta operación
* @ return <TT>base</TT>^<sup><TT>pow</ TT></sup>Dentro de Modular
* Pertenece a<TT>mod</TT>.
*/
Descodificación pública codificada de enteros grandes (base de enteros grandes){
BigInteger a = one;
BigInteger s = base;
BigInteger n = myKey
And (! n . es igual a (cero)) {
if (! n . mod (dos) . es igual a (cero) ))
a = a .Operación de multiplicación. mod(miMod);
s = s.pow(2). mod(myMod);
n = n.divide(dos);
}
Devuelve a;
}
}
Las siguientes son descargas de código para dos versiones del algoritmo RSA implementado en JAVA:
1.Desde /code.aspx? Paquete de código fuente del algoritmo RSA con ID=27020;
/rsa/