Hej alle
Nu funker det - vist nok. Jeg har i hvert fald fået én rutine til at arbejde
med 16-bit format, og den samme bruges til både kryptering og dekryptering.
Jeg har været nødt til at skrive mine egne int-læse- og -skrivemetoder.
Jeg har i indlægget udvidet min linjelængde til 78 og ombrudt nogle
udskriftlinjer som ellers blev for lange, men koden er lige til at kompilere.
Den metode der genererer nøgler, er lidt primitiv, men principielt rigtig nok.
Den kan bare ikke sikre at nøglerne er store nok. De burde jo også være på 16
bit.
// RSA-kryptering - nøgleberegning samt kryptering og dekryptering
// Bertel Lund Hansen, sep. 2002
import java.io.*;
class RSA {
// ======== Trace-flag ========
static final boolean trace=false;
// ======== Hjælperutiner ========
// SIZE=4 bevirker at man somme tider løber ind i en fortegnsbit
// når to ints ganges til en long. SIZE=3 dur bare ikke.
// Der er internt brugt long-variable for at undgå et tilsvarende
// problem med int når to 16-bit værdier ganges sammen.
static final int SIZEofINT=2;
static long findPrimtal (long kandidat) {
long limit;
boolean prim;
--kandidat;
if (kandidat%2==0) --kandidat;
do {
kandidat+=2;
limit=(int) Math.sqrt(kandidat);
prim=true;
for (int div=3; div<=limit; div+=2) {
prim=kandidat%div!=0;
}
} while (!prim);
return kandidat;
}
static long gcd (long x, long y) {
long rest=y; y=x;
do { x=y; y=rest; rest=x%y; } while (rest>0);
return y;
}
static long readIntBytewise (DataInputStream ind) throws IOException {
int nr=0, n;
int readBytes[] = new int[SIZEofINT];
long value=0; // Teknisk init.
try {
for (nr=0; nr<SIZEofINT; ++nr) readBytes[nr]=ind.readUnsignedByte();
value=readBytes[0];
for (nr=0; nr<SIZEofINT; ++nr) value=value*256+readBytes[nr];
} catch (EOFException e) {
// Her ryger vi ned hvis der til sidst ikke er bytes nok at læse.
// nr registrerede hvor mange der var.
value=0;
for (n=0; n<nr; ++n) value=value*256+readBytes[n];
}
return value;
}
static void writeIntBytewise (long value, DataOutputStream ud)
throws IOException {
int nr=0;
for (nr=0; nr<SIZEofINT; ++nr) {
ud.writeByte((int) (value%256));
value/=256;
}
}
static void help () {
System.out.println
("\n RSA kan generere nøgler, kryptere og dekryptere en fil.\n");
System.out.println
(" -n T frembringer et sæt nøgler.");
System.out.println
(" T bestemmer starttallet og dermed størrelsen.\n");
System.out.println
(" -k N nøgle <indfilnavn> <udfilnavn>");
System.out.println
(" (de)krypterer indfilen og skriver til udfilen.\n");
}
// ======== Hovedrutiner ========
static void findNøgler (long tal) {
long p1, p2, nøgle, z, privat, offentlig;
p1=findPrimtal(tal);
p2=findPrimtal(p1+2);
System.out.println("Primtal: "+p1+", "+p2);
nøgle=p1*p2; z=(p1-1)*(p2-1);
// Vælg privat nøgle så privat og z er indbyrdes primiske.
privat=(int) Math.sqrt(nøgle);
while (gcd(privat,z)!=1) {
++privat;
if (trace) System.out.println("Prv: "+privat);
}
// Vælg offentlig nøgle så z går op i privat*offentlig-1.
offentlig=z;
while ((privat*offentlig-1)%z!=0) {
++offentlig;
if (trace) System.out.println("Off: "+offentlig);
}
System.out.println("Nøgler: ("+nøgle+","+privat+") -
("+nøgle+","+offentlig+")");
}
// ======== crypt tager 1 int og producerer 1 int
// Men undervejs kan der godt opstå long-værdier.
static void crypt (long ngl, long key, String indfil, String udfil)
throws IOException {
long value=0, tmp;
System.out.println("\n Krypterer ...\n");
DataInputStream in =
new DataInputStream (new FileInputStream(indfil));
DataOutputStream out =
new DataOutputStream (new FileOutputStream(udfil));
while (in.available()>0) {
value=readIntBytewise(in);
tmp=1;
for (int n=0; n<key; ++n) tmp=(tmp*value)%ngl;
writeIntBytewise((int) value,out);
}
in.close();
out.flush();
out.close();
}
// ======== main() ========
public static void main(String args[]) throws IOException {
long n=0, k=0;
int nr=0;
String temp;
char cmd;
if (args.length>0) {
String kommando=args[0];
if ( kommando.length()==1 || ("-/").indexOf(kommando.charAt(0))==-1) {
help();
System.exit(1);
}
cmd=(kommando.toLowerCase()).charAt(1);
try {
++nr; n=Long.parseLong(args[nr]);
if (cmd!='n') {
++nr; k=Long.parseLong(args[nr]);
++nr; temp=args[nr];
++nr; temp=args[nr];
}
} catch (Exception e) {
switch (nr) {
case 1: System.out.println
("Angiv det fælles tal (eller et starttal)."); break;
case 2: System.out.println
("N: "+n+" Angiv krypteringsnøglen."); break;
case 3: System.out.println
("Angiv den fil der skal (de)krypteres."); break;
case 4: System.out.println
("Angiv den fil der skal skrives til."); break;
}
System.exit(1);
}
switch (cmd) {
case 'n': findNøgler(n); break;
case 'k': crypt(n,k,args[3],args[4]); break;
default: help();
}
}
else help();
}
}
--
Bertel
http://bertel.lundhansen.dk/ FIDUSO:
http://fiduso.dk/