-
Notifications
You must be signed in to change notification settings - Fork 0
/
EmpaquetarExamen.java
207 lines (154 loc) · 7.72 KB
/
EmpaquetarExamen.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
import java.io.*;
import java.nio.file.*;
import java.security.*;
import java.security.spec.*;
import javax.crypto.*;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
/**
*
* @author lfcounago
*/
public class EmpaquetarExamen {
public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException,
NoSuchProviderException, SignatureException, InvalidKeySpecException, IOException, NoSuchPaddingException,
IllegalBlockSizeException, BadPaddingException {
if (args.length != 4) {
mensajeAyuda();
System.exit(1);
}
/* Cargar provider */
Security.addProvider(new BouncyCastleProvider()); // Usa provider BC
/* CIFRAMOS EL EXAMEN DEL ALUMNO */
// Generamos el fichero con la clave simétrica
System.out.println("------Generando clave simétrica-------");
SecretKey clave = generarClaveSecreta();
System.out.println("Clave simétrica generada correctamente");
System.out.println("--------------------------------------\n");
// Cifrar el examen con la clave secreta simétrica
System.out.println("-----Cifrando el examen-----");
byte[] examenCifrado = cifradoDES(clave, args[0]);
System.out.println("Examen cifrado correctamente");
System.out.println("----------------------------\n");
/* CIFRAMOS LA CLAVE SECRETA */
// Cifrar la clave simétrica con la clave pública del profesor con RSA
System.out.println("--Cifrando clave simétrica--");
byte[] claveSimetricaCifrada = cifrarClaveSimetrica(clave, args[2]);
System.out.println(" Clave cifrada correctamente");
System.out.println("----------------------------\n");
/* GENERAMOS LA FIRMA */
// Recuperar clave privada del alumno
PrivateKey KRalumno = recuperClavePrivada(args[3]);
// Generar firma
System.out.println("-------Generado firma------");
byte[] firma = generarFirma(examenCifrado, claveSimetricaCifrada, KRalumno);
System.out.println("Hash generado correctamente");
System.out.println("---------------------------\n");
/* GENERAR PAQUETE */
// Guardamos los datos obtenidos en el paquete
System.out.println("-------Creando paquete-------");
Paquete p = new Paquete();
p.anadirBloque("Examen cifrado", examenCifrado);
System.out.println("Examen cifrado añadido");
p.anadirBloque("Clave secreta cifrada", claveSimetricaCifrada);
System.out.println("Clave secreta cifrada añadida");
p.anadirBloque("Firma cifrada", firma);
System.out.println("Firma cifrada añadida");
p.escribirPaquete(args[1]);
System.out.println("Paquete creado correctamente");
System.out.println("-----------------------------\n");
}
/*
* Función para generar la clave simétrica con la que se va a cifrar el examen
* Generará un fichero clave.secreta donde se guardará la clave cifrada
* Delvolverá la clave simétrica para cifrar el examen
*/
public static SecretKey generarClaveSecreta() throws NoSuchAlgorithmException, IOException {
Security.addProvider(new BouncyCastleProvider());
/* Crear e inicializar clave DES */
KeyGenerator generadorDES = KeyGenerator.getInstance("DES");
generadorDES.init(56); // clave de 56 bits
SecretKey claveSecreta = generadorDES.generateKey();
/* Volcar clave secreta a fichero */
// Escribirla directamente a fichero binario
FileOutputStream out = new FileOutputStream("clave.secreta");
out.write(claveSecreta.getEncoded());
out.close();
return claveSecreta;
}
/*
* Función para cifrar el examen con la clave secreta
* Devolvemos el examen cifrado
*/
public static byte[] cifradoDES(SecretKey clave, String examen) throws NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, IOException {
/* Crear cifrador */
Cipher cifrador = Cipher.getInstance("DES/ECB/PKCS5Padding");
/* Inicializar cifrador en modo CIFRADO */
cifrador.init(Cipher.ENCRYPT_MODE, clave);
// Leemos todos los bytes del fichero y lo ciframos
byte[] examenCifrado = cifrador.doFinal(Files.readAllBytes(Paths.get(examen)));
return examenCifrado;
}
/*
* Función para cifrar la clave simétrica (clave con la que se cifró el examen)
* con la clave pública del profesor
* Devolverá la clave cifrada
*/
public static byte[] cifrarClaveSimetrica(SecretKey clave, String publicaProfesor)
throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, IOException,
NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
// SecretKeyFactory secretKeyFactoryDES = SecretKeyFactory.getInstance("DES");
// Obtenemos la clave pública del profesor
PublicKey KUprofesor = recuperClavePublica(publicaProfesor);
// Crear cifrador RSA
Cipher cifrador = Cipher.getInstance("RSA", "BC"); // Hace uso del provider BC
// Poner cifrador en modo CIFRADO
cifrador.init(Cipher.ENCRYPT_MODE, KUprofesor); // Cifra con la clave pública
// Cifro con la clave pública
byte[] claveCifrada = cifrador.doFinal(clave.getEncoded());
return claveCifrada;
}
/*
* Función para recuperar la clave pública
* Devuelve la PublicKey correspondiente
*/
public static PublicKey recuperClavePublica(String clavePublica)
throws NoSuchAlgorithmException, NoSuchProviderException, IOException, InvalidKeySpecException {
// Crear KeyFactory formato RSA
KeyFactory keyFactoryRSA = KeyFactory.getInstance("RSA", "BC"); // Hace uso del provider BC
// Recuperar clave publica desde datos codificados en formato X509
X509EncodedKeySpec clavePublicaSpec = new X509EncodedKeySpec(Files.readAllBytes(Paths.get(clavePublica)));
PublicKey KU = keyFactoryRSA.generatePublic(clavePublicaSpec);
return KU;
}
/*
* Función para generar la firma del examen cifrado y la clave simétrica cifrada
* Devuelve la firma correspondiente
*/
public static byte[] generarFirma(byte[] examenCifrado, byte[] claveSimetricaCifrada, PrivateKey KRalumno)
throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, SignatureException {
Signature firmaAlumno = Signature.getInstance("MD5withRSA", "BC");
firmaAlumno.initSign(KRalumno);
firmaAlumno.update(examenCifrado);
firmaAlumno.update(claveSimetricaCifrada);
byte[] firmaAlumnoFinal = firmaAlumno.sign();
return firmaAlumnoFinal;
}
/*
* Función para recuperar la clave privada
* Devuelve la PrivateKey correspondiente
*/
public static PrivateKey recuperClavePrivada(String clavePrivada)
throws NoSuchAlgorithmException, NoSuchProviderException, IOException, InvalidKeySpecException {
KeyFactory keyFactoryRSA = KeyFactory.getInstance("RSA", "BC"); // Hace uso del provider BC
PKCS8EncodedKeySpec clavePrivadaSpec = new PKCS8EncodedKeySpec(Files.readAllBytes(Paths.get(clavePrivada)));
PrivateKey KR = keyFactoryRSA.generatePrivate(clavePrivadaSpec);
return KR;
}
public static void mensajeAyuda() {
System.out.println("Empaquetador de exámenes");
System.out.println(
"\tSintaxis: java -cp \".;bcprov-jdk18on-176.jar\" EmpaquetarExamen examen paquete .\\profesor.publica .\\alumno.privada");
System.out.println();
}
}