93 lines
3.4 KiB
Java
93 lines
3.4 KiB
Java
package com.crypto;
|
|
import java.math.BigInteger;
|
|
|
|
public class RSA {
|
|
|
|
// Struttura che rappresenta il mazzo di chiavi che viene generato con la
|
|
// funzione defkeys()
|
|
public record RSAkeys(BigInteger n, BigInteger e, BigInteger d) {}
|
|
|
|
static RSAkeys defkeys(int primesize) {
|
|
// Generiamo i numeri primi p e q, con la size scelta dall'utente
|
|
BigInteger p = Utilities.GenPrime(primesize);
|
|
BigInteger q = Utilities.GenPrime(primesize);
|
|
|
|
// Rigeneriamo q se p e q sono uguali (just in case)
|
|
while (p.equals(q)) {
|
|
q = Utilities.GenPrime(primesize);
|
|
}
|
|
|
|
// Calcoliamo n come prodotto pq
|
|
BigInteger n = p.multiply(q);
|
|
|
|
// Calcoliamo la funzione di Eulero phi (o m)
|
|
BigInteger phi = (p.subtract(BigInteger.ONE)).multiply((q.subtract(BigInteger.ONE)));
|
|
|
|
// Calcoliamo la chiave pubblica e, rendendola prima rispetto a phi
|
|
BigInteger e = Utilities.CalculateE(phi);
|
|
|
|
// Stampa i risultati per il debug
|
|
System.out.println("\n--- RISULTATI GENERAZIONE ---");
|
|
System.out.println("Bit di p generato: " + p);
|
|
System.out.println("Bit di q generato: " + q);
|
|
System.out.println("Bit del modulo n: " + n);
|
|
System.out.println("Bit di phi generato: " + phi);
|
|
System.out.println("Bit del modulo e: " + e);
|
|
|
|
// Calcoliamo la chiave privata d (o k)
|
|
BigInteger d = e.modInverse(phi);
|
|
|
|
return new RSAkeys(n, e, d);
|
|
}
|
|
|
|
// ---------------------- Encrypting e Decrypting di valori numerici ----------------------------------
|
|
|
|
static BigInteger encrypt(BigInteger m, BigInteger e, BigInteger n) {
|
|
// Controllo vitale: m deve essere positivo e minore di n
|
|
if (m.compareTo(BigInteger.ZERO) < 0 || m.compareTo(n) >= 0) {
|
|
throw new IllegalArgumentException(
|
|
"Il messaggio deve essere positivo e minore del modulo n! - Cifratura annullata");
|
|
}
|
|
// Cifriamo con i nostri parametri kpb(e,n)
|
|
return m.modPow(e, n);
|
|
}
|
|
|
|
static BigInteger decrypt(BigInteger c, BigInteger d, BigInteger n) {
|
|
// Decifriamo con i nostri parametri kpb(e,n)
|
|
return c.modPow(d, n);
|
|
}
|
|
|
|
// ---------------- Encrypting e Decrypting di valori alfanumerici ---------------------------
|
|
|
|
static String encrypt(String input, BigInteger e, BigInteger n) {
|
|
// Calcoliamo la lunghezza dei blocchi g e la approssimiamo per difetto
|
|
// basta contare i bit necessari per rappresentare n e poi fare - 1 perchè non ci serve la precisione
|
|
int g = n.bitLength() - 1;
|
|
if (g == 8)
|
|
g = 7;
|
|
|
|
// Conversione da stringhe a bytes( ASCII ma in decimale !)
|
|
byte[] m = input.getBytes();
|
|
|
|
// Conversione in Binario e unificazione in un unica stringa
|
|
String data = Utilities.BytestoBin(m);
|
|
|
|
// Divisione del messaggio e cifratura
|
|
String res = Utilities.DivideetImpera(data,g,e,n);
|
|
return res;
|
|
}
|
|
|
|
static String decrypt(String m, BigInteger d, BigInteger n) {
|
|
// Calcolo di z
|
|
int z = n.bitLength();
|
|
if (n.and(n.subtract(BigInteger.ONE)).equals(BigInteger.ZERO))
|
|
z--; // n è una potenza esatta di 2, togli 1
|
|
// Calcolo di g
|
|
int g = n.bitLength() - 1;
|
|
if (g == 8)
|
|
g = 7;
|
|
String res = Utilities.ImperaetDivide(m, z, g, d, n);
|
|
return res.toString();
|
|
}
|
|
|
|
} |