Professional Documents
Culture Documents
Author:
Luis Hernando Santamarı́a Bernales
Director:
Cesar Leonardo Niño, Ph.D.
Abstract i
Contents ii
List of Figures iv
List of Tables v
1 Introduction 1
2 Background Information 3
2.1 Overview of AES . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2 Overview of RSA . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.2.1 Key Generation, Encryption and Decryption . . . . . . . . . 5
2.2.2 Confidentiality, Authentication and no repudiation . . . . . 6
2.3 SMTP Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.4 PGP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3 Specifications 10
3.1 Key management server . . . . . . . . . . . . . . . . . . . . . . . . 10
3.2 Client System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3.3 USB token . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.4 Mail Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.5 Communication Protocols . . . . . . . . . . . . . . . . . . . . . . . 12
3.5.1 Sending an Email Operation . . . . . . . . . . . . . . . . . . 12
3.5.2 Receiving and Email Operation . . . . . . . . . . . . . . . . 13
3.5.3 Key Management Server Operation . . . . . . . . . . . . . . 13
4 System Development 15
5 Analysis of Results 17
5.1 Analysis of the proposed system against PGP . . . . . . . . . . . . 20
5.2 System Performance . . . . . . . . . . . . . . . . . . . . . . . . . . 21
6 Conclusions 25
ii
Contents iii
Bibliography 26
iv
List of Tables
v
Chapter 1
Introduction
Ordinary email does not provide techniques to assure integrity, privacy or authen-
tication, therefore cryptography techniques are needed to encrypt a message so
that it is not intelligible. The intention is that an encrypted message can only
be decrypted by authorized personnel. Cryptography refers to the art of secret
writing, which enables someone to secure the content of a message from unautho-
rized recipients. The two types of cryptography are symmetric cryptography and
asymmetric cryptography. Symmetric key algorithms use the same key to encrypt
and decrypt, such as the DES algorithm (Data Encryption Standard), Triple DES
[2] and the AES (Advanced Encryption Standard) [3].
is lost. In 1974, Diffie and Hellman first proposed a class of public key systems [5].
Essentially, the key is used by all the people to encrypt messages to a given user.
The system also has a private key used by the final user to decrypt the message.
Public key algorithms have the principle that it is too difficult to calculate the
private key from the public key, usually based on the difficulty of factoring large
numbers and computing discrete logarithms. One of the most popular public key
algorithms is the RSA (Rivest , Shamir , Adleman) [6].
Security in email has been approached from different perspectives, for example in
[7] an email architecture is proposed using TLS/SSL which provides protection
against viruses as well as spam email. Available email standards such as S/MIME
[8] and OpenPGP [9] focus on content protection using cryptographic algorithms.
One drawback of security email features is that a lot of them are not used because
the users do not know how to configure them, leaving the system exposed to
the loss of important information. Another solution in [10] describes a certificate-
based solution to check the authenticity of users, where the receiver has to show his
certificate before getting the message. Other solutions make use of a smart card to
store user credentials, as it is proposed in [11]. There have been proposals on hybrid
encryption that make use of both symmetric-key and public-key cryptographic
algorithms like [4] using DES and AES combined with RSA to cypher plain text.
Background Information
AES is a based on the Rjindael block cipher and it has become the successor of DES
being chosen by the US National Institute of Standards and Technology (NIST),
which specifies the cryptographic algorithm to protect sensitive information by
the U.S. Government. Rinjdael Algorithm was chosen to be the AES in a quite
demanding contest that had the following rules:
3
Chapter 3. Background Information 4
The AES algorithm is summarized in Figure 2.1. The first step is to copy the
plain text in the array state in order to process it during successive rounds. Then,
it goes to a first round of AddRoundKey. The cycle runs 10 iterations, one per
round, and transforms the array state in each iteration.
• ShiftRows Transformation: This step shifts left each of the four rows. The
0th row is rotated 0 bytes (no change), row 1 is rotated 1 byte, and so on.
• Add Round Key: Apply XOR to this round key within (state).
The RSA algorithm key generation proccess, encryption and decryption is ex-
plained below in Section 2.2.1.
Chapter 3. Background Information 5
Two large pseudo-random prime numbers are selected, that are called p and q
which must be kept in secret. ”Large” in cryptography usually means 512 bits or
more [14]. After selecting the prime numbers the algorithm works as follows:
The public key is composed by the pair (n, e) and the private key is the pair
(n, d). The encryption is done by equation 2.1 where the input M is the message
(represented by a positive integer) and the output C is the cipher-text.
C = M e mod(n) (2.1)
The message is decrypted by using equation 2.2, and extracting the plain-text
from the integer representative M . Encryption and decryption process are inverse
because of the relationship of exponents e and d.
M = C d mod(n) (2.2)
Authentication [18] is the process of identifying the sender and/or the receiver
and no repudiation is the process of preventing a sender from denying transmitted
data. Both attributes will be complied if the sender A uses its own secret key
(KSA ) when encrypting the message. The recipient will use the Public Key of A
for decrypting (KPA ) so he can be sure that the message comes from user A. This
has a property of a Digital Signature where anyone can verify the signature, but
only the originating part can generate it [14]. This can be seen in Figure 2.3.
The three attributes can be achieved if there is a double RSA encryption, each
user with a different pair of keys. This can be seen in Figure 2.4.
SMTP (Simple Mail Transfer Protocol) was originally defined in RFC 821 to trans-
fer emails between stations. Currently, the SMTP protocol is defined in RFC 5321
[15]. The protocol focuses on how messages are transmitted.
When sending a message the SMTP protocol makes uses of port 25 to establish
a TCP connection to the SMTP server. The SMTP server indicates whether is
willing to receive the e-mail, and it starts by sending the source and destination
address, and then the message. If the operation is complete the server replies with
an acknowledgement of received (ACK). The SMTP operating scheme can be seen
in Figure 2.5.
2.4 PGP
In Figure 2.6 the encryption and decryption process for PGP is shown. It first
take a plain text and calculate the Message Disgest using MD5. Then it creates
a random session key generated from movements of the keyboard and mouse to
encrypt the message using symmetric algorithms IDEA or CAST. Finally it ciphers
Chapter 3. Background Information 9
the session key using public cryptography with RSA or DSA with the public key
of the receiver. Both encrypted message and encrypted session key are send to
the receiver by E-mail. One main advantage of PGP is that the list of support
algorithms have been permanently growing.
For decryption the receiver have to known which algorithms were used to en-
crypted, this information needs to be included within the information received
[17]. The receiver uses its own private key to obtain the one time session key. It
then uses the session key and gets the message and signature which can be validate
with the public key of the sender.
Chapter 3
Specifications
The system consists of a key management server, the client system, the USB
token and e-mail server to exchange messages. There are several protocols for
communication between the client and server key management developed. All
parts are implemented using Java programming language.
This server manage and stores all public keys of the users of the system, they may
be request by a user when decrypting a message. The server is managed by a
single administrator who is responsible for the management of public keys of the
users of the company. The server will also store encrypted symmetric keys sent by
users when sending an email with an ID to identify the message.
It is a client module to be run on the user PC and has built-in security features.
The customer must ensure access control using a USB Token and a secret key to
properly identify the user. The client must encrypt the contents of email messages
with a 128 AES key and sharing this key through the key management server using
asymmetric cryptography.
10
Chapter 3. Background Information 11
Each user of the system must have a USB Token assigned internally which must
contain private login information of their email account. When the email client
starts, the system verifies if there is a USB token plugged into the system. If the
USB is not connected, the system asks for it through a message. Once there is
a valid Token within the system it takes its email account information (user and
key) in order to send or receive messages. The client executes a loop to verify
that the USB remain connected at all times, at the time it is removed the user is
automatically logout of the system as seen on Figure 3.1.
The email server is used by clients to exchange messages. Mail server relays all
messages using Simple Mail Transport Protocol.
Chapter 3. Background Information 12
Communication protocols are also implemented between the client and the server
key management to send and receive messages.
The user makes use of the client interface to send an email. An AES-128 Key is
generated and once the user press the Send button the content is encrypted with
this key and connection with the Key Management Server starts. The client asks
for the Public Key of the receiver and then it begins the double encryption process
of the AES-128 Key. Finally the client sends this encrypted key to the database
server and the email is send as seen on Figure 3.2.
When an encrypted message is receive the client starts the communication with
the Key Management Server. The client asks for the encrypted AES-128 Key
and the sender Public Key. Then it begins the asymmetric decryption process to
obtain the AES-128 Key which is then use to decrypt the content by the client.
This can be seen on Figure 3.3
The key management server keeps running on listening state waiting for a connec-
tion request from a client. Once the connection request the client identifies and
Chapter 4. Specification 14
confirms that the connection was established is received. There are three kind
requests that the server can receive from the client. If a 001 request ID is received,
it means that the client is sending encrypted secret AES Key. The server verifies
the values of sender and recipient and stores this information. If a 010 request
ID is received, it means that the client is asking for a Public Key of a user. The
server must verify if this key exists within its database and send it to the client. If
a 011 request ID is received, it means that a client is asking for a symmetric AES
key encrypted. The server verifies the sender and recipient address values, and it
must send this information to the client. This can be seen on Figure 3.4
System Development
AES have proven to be a highly secure algorithm against many attacks such brute-
force, differential and linear attacks [19], and continues to be the best single key
algorithm because of security, cost and implementation. AES has less imple-
mentation complexity and can easily encrypt large data, in comparison with the
asymmetric algorithm RSA, which uses large keys and so it requires more com-
putational resources for encryption. However, the secret key distribution remains
an issue of symmetric algorithms. In order to solve this issue it is proposed the
use of a hybrid encryption system that uses RSA for distributing the secret key of
AES. The system also uses a token device for physical authentication that helps
preventing the leak of sensitive information.
The token device stores information such name and password of a user (email
account) and the requirement is that it must be connected at all times in order
to use the application. This authentication token have an important role in the
system since it is assuring that a valid user is the one using the system. The
token is a small device in this case simulated by means of a USB. This is a major
advantage since there is no need of a reader, because just about every computer
on the planet has one or more USB connector [20]. If the USB token is unplugged,
then the system is automatically blocked preventing that any other user seeing
any information or from attempting to use the email application.
The system also makes use of a database server to store the public key of the
users and the AES encrypted keys that were generated when an email was sent.
This database server must be a trusted third party inside the organization so it
15
Chapter 5. System Development 16
can assert that a public key belongs to a particular user. All components of the
system and its scheme can be seen in Figure 4.1.
The selected 128-bit key (K) which was used to encrypt the message, is then
encrypted twice using the RSA algorithm. The user A who wants to send a
message to user B, uses its own secret RSA key (KSA ) to encrypt K becoming K∗
and then uses the public RSA key of B (KPB ) to encrypt one more time the previous
result. This double encryption guarantees the confidentiality, authentication and
no repudiation in the communications as it was seen in the previews section. When
the user B gets connected, it receives the encrypted AES email and the encrypted
AES key (K ∗ ∗). Then, it starts the process of deciphering the K ∗ ∗ with the
RSA algorithm, first with its own secret key (KSB ) and then with the public key
of A (KPA ) to finally obtain K. K is then used to decipher the encrypted email
(AES algorithm).
Chapter 5
Analysis of Results
The application was tested by parts. First, the AES encryption and decryption
process was proven against verified examples such the ones in Advanced Encryp-
tion Standard (AES) (FIPS PUB 197) [21] and The Advanced Encryption Stan-
dard Algorithm Validation Suite (AESAVS) [22]. An example of the encryption
process is shown in Figure 5.1 the inputs Plain-text and Key where selected ac-
cording to the example C.1 in [21] and the output matches correctly.
The RSA key generation, encryption and decryption operation were also tested.
In Figure 5.2 the values 47 and 59 were chosen for p and q respectively. The e
value was selected to be 17 to match the example in [23] chapter 8. The rest
of the values were properly calculated, n = p ∗ q = 47 ∗ 59 = 2773, d = 157,
totient(n) = 46 ∗ 58 = 2668. The characters were substitute using two digits for
each letter: blank = 00, A = 01, B = 02, . . ., Z = 26. The plain-text ”ITS ALL
GREEK TO ME” was then encrypted and the output matches correctly as in [23].
17
Chapter 6. Analysis of Results 18
Once the two algorithms were tested successfully, they were implemented on the
email client. In Figure 5.3 it can be seen that the plain-text ”Hello World.” is
send.
In Figure 5.4 the message is receive and the text is in fact encrypted by an AES-
128 Key and in Figure 5.5 it can be seen the message decrypted when using the
USB Token and executing the RSA and AES decryption process.
The proposed system and PGP solution provide security for e-mail application
using a hybrid cryptographic system that consists of symmetric cryptography and
public key cryptography. PGP does use some of the existing algorithms such as
MD5, RSA, and IDEA integrated with the application for e-mail security [24] as
so it is the proposed system. The way that the encryption and decryption is done
is slightly different. The proposed system uses the RSA algorithm to encrypt
twice using two pairs of keys. In the other hand, PGP uses RSA in one way
to protect the secret key, but it also make use of MD5 for signing the message.
Accordingly, both proposed solutions can provide confidentiality, authentication
and non-repudiation.
However the PGP solution lacks of security when multiple users make use of the
same computer according to Phil Zimmermann creator of PGP [25]. There are
several multi risk associated on multi user system such plain text can not be protect
it while it is still being plain text. For example if the user leaves the system it
could be exposed for someone else to access its private information. Also having
a single private key to log on the application is very risky. If somehow it gets
compromised all the security will be lost.
The proposed system is more secure because it uses two mechanisms for controlling
access. The key that only the user knows to enter the system and a security token
that validates the user’s identity. So that if the user is leaves the computer with
the Token, the application automatically closes and does not allow a different user
to see your information. Also if your secret key is compromised, the attacker would
still need the USB Token to access the system.
Chapter 6. Analysis of Results 21
The system was tested by measuring the time it takes for the RSA algorithm to
encrypt the AES secret key that consists of 128 bits for all cases. Tests were made
using RSA keys that were previously calculated from P and Q values of 512, 1024
and 2048 bits. The tests were run on a computer with the characteristics of the
table 5.1.
For each key size, a total of 50 measurements were performed for encryption and
decryption using NanoTime Java method which measures the elapsed time with a
nanosecond precision [26].
Using a 512 bit key for RSA algorithm, the average time to encrypt a 128 AES
key is 80,313 ms. The average time for decryption is 100,944 ms. The standard
deviation for the encryption process is 6,434 ms and the decryption process is
11,17 ms. It can be seen that decryption process shows a coefficient of variation
of 11,06% which is slightly high, however the impact is not noticeable in the use
of the application. The measured times for encryption and decryption in the test
can be seen in Figure 5.6.
The average time to encrypt with a 1024 RSA key is 538,361 ms and the average
time for decryption is 645,299 ms. The standard deviation for the encryption
process is 28,024 ms and the decryption process is 22,399 ms. The coefficients
of variation are 5,2% and 3,4% respectively showing an acceptable result for the
tests. The measured times for encryption and decryption in the test can be seen
in Figure 5.7.
Finally using a 2048 bit key for RSA algorithm, the average time to encrypt a 128
AES key is 3913,414 ms. The average time for decryption is 4654,309 ms. The
standard deviation for the encryption process is 141,214 ms and the decryption
process is 130,676 ms. It can be seen that encryption process shows a coefficient
of variation of 3,6% and decryption process 2,8%, which implies less dispersion
Chapter 6. Analysis of Results 22
Figure 5.6: Encryption and Decryption time with a 512 bit RSA Key.
Figure 5.7: Encryption and Decryption time with a 1024 bit RSA Key.
compared to the average. The measured times for encryption and decryption in
the test can be seen in Figure 5.8.
In Table 5.2 it can be seen the values for the average, standard deviation and
coefficient of variation calculated from a sample of 50 test for each RSA key size
encryption and decryption process.
It is observed from Table 5.3 the comparison of elapsed time using different sizes
of RSA pair of keys to encrypt the secret shared key of 128 bits.
In Table 5.4 it shows the time to decrypt the secret shared key, and it can be seen
that it is higher than the encryption time for all the key sizes. This times are
Chapter 6. Analysis of Results 23
Figure 5.8: Encryption and Decryption time with a 2048 bit RSA Key.
Table 5.2: Mean, standard deviation and coefficient of variation for encryption
and decryption process with different sizes of RSA key.
tolerable for an email application but the most important is the fact that it would
not increase since the system is using a unique 128 bit AES key to encrypt and
decrypt. CPU performance has a direct impact on the overall results to process
the cryptography operations.
The normal key sizes for RSA are 512, 1024 and 2048 bits so if the crypto system
is implemented, there is need to have a discussion regarding performances against
security priorities. For instance, it is said that 1024-bit keys could be compromised
in the near future so a 2048-bit key would be the choice in order to have a more
robust implementation.
According to Figure 5.9 where both encryption and decryption times are shown,
it can bee seen that that the time is increased by a ratio of 6 or 7 times each time
the key size is incremented.
Conclusions
In this project degree it is presented a hybrid encryption scheme with the AES and
RSA algorithms using an external Token device for authentication for enterprise
email purposes.
RSA is an asymmetric algorithm than can satisfy most security concerns such con-
fidentiality, authentication and non-repudiation, when the RSA is implemented in
both communication ways. However the main drawback of RSA is the computa-
tional overhead because of the key size.
AES have less implementation complexity and it is one of the most strongest
single-key algorithms. In this case, the key distribution is considered to be the
major drawback.
An optimal solution was implemented using the AES 128-bit to encrypt the mes-
sages, taking advantage of its speed, and using RSA for sharing the secret key
safely. The token USB increases the security of the system by authenticating
users when using the application.
25
Bibliography
[1] Simson L. Garfinkel, David Margrave, Jeffrey I. Schiller. How to Make Secure
Email Easier To Use. CHI 2005, April 2–7, 2005, Portland, Oregon, USA.
[2] RFC 2420, The PPP Triple-DES Encryption Protocol (3DESE), Nentec
GmbH, 1998.
[3] RFC 3394, Advanced Encryption Standard (AES) Key Wrap Algorithm, RSA
Laboratories, 2002.
[6] RFC 2313, PKCS #1: RSA Encryption, RSA Laboratories East, 1998.
[10] H.-M. Sun, B.-T. Hsieh, and H.-J. Hwang, “Secure Email protocols providing
perfect forward secrecy” Published in IEEE Communications Letters, Volume:
9, Issue: 1, 2005.
[11] G. Kardas and E. Celikel, “A Smart Card Mediated Mobile Platform for Se-
cure E-Mail Communication” Fourth International Conference on Information
Technology, 2007.
26
Bibliography 27
[12] D.Choi, S. Jin and H. Yoon, A method for Preventing the Leakage of Per-
sonal Information on the Internet, IEEE Tenth International Symposium,
Consumer Electronics, 2006.
[20] Sean Turner, Russ Housley. Implementing Email and Security Tokens: Cur-
rent Standards, Tools, and Practices. Wiley Publishing, Inc. 2008.
[23] R.L. Rivest, A. Shamir, and L. Adleman, ”A Method for Obtaining Digital
Signatures and Public-Key Cryptosystems”, 1978.
[24] D. Kuobin, PGP e-mail protocol security analysis and improvement program,
International Conference on Intelligence Science and Information Engineering,
2011.
Bibliography 28
The RSA.java is the class that implements the logic of the RSA algorithm. It con-
tains the key generation process of the RSA algorith. The class java.util.Random
is used for the prime number generation P and Q. All variables are calculated in
order to get the Pair of keys.
For encryption and decryption of RSA the method modPow is used which allows
us to get the BigInteger whose value is (this exponent mod m).
package l o g i c a . r s a ;
import j a v a . math . B i g I n t e g e r ;
import j a v a . u t i l . A r r a y L i s t ;
import j a v a . u t i l . Random ;
import l o g i c a . u t i l . C o n s t a n t e s ;
import l o g i c a . u t i l . M e t o d o s U t i l e s ;
/∗ ∗
∗ @author L u i s H Santamaria
∗/
p u b l i c c l a s s RSA {
private BigInteger p ;
private BigInteger q ;
p r i v a t e ParDeClaves c l a v e s ;
p r i v a t e S t r i n g desc = ”” ;
/∗ ∗
∗ Constructor
∗
∗ @param privadaD
∗ @param p u b l i c a E
∗ @param n
∗/
29
Annex A. Source Code 30
/∗ ∗
∗ Constructor
∗/
p u b l i c RSA( ) {
generaPrimos ( ) ;
generaClaves () ;
S t r i n g s = ”P : ” + p + ”\ t ” + ”Q: ” + q
+ ” \ t ” + ”N: ” + c l a v e s . getN ( )
+ ” \ t ” + ”D: ” + c l a v e s . getPrivadaD ( ) . getD ( )
+ ” \ t ” + ”E : \n” + c l a v e s . g e t P u b l i c a E ( ) . getE ( ) ;
addDesc ( s ) ;
}
/∗ ∗
∗ Method i n c h a r g e o f g e n e r a t e p r i m e s P and Q t o c a l c u l a t e t h e
key .
∗/
p r i v a t e v o i d generaPrimos ( ) {
p = new B i g I n t e g e r ( C o n s t a n t e s . BIT LONGITUD, C o n s t a n t e s .
LIM PRIMO RSA , new Random ( ) ) ;
/∗ ∗
∗ Generate t h e k e y s
∗/
private void generaClaves () {
BigInteger e ;
BigInteger d ;
BigInteger n ;
BigInteger toTient ;
// n = p ∗ q
Annex A. Source Code 31
n = p . multiply (q) ;
// t o t i e n t = ( p−1) ∗ ( q−1)
toTient = p . subt ract ( BigInteger . valueOf (1) ) ;
toTient = toTient . multiply ( q . subtr act ( BigInteger . valueOf (1) ) )
;
// We s e l e c t a coprime number E o f T o t i e n t
do {
e = new B i g I n t e g e r ( 2 ∗ C o n s t a n t e s . BIT LONGITUD, new
Random ( ) ) ;
} w h i l e ( ( e . compareTo ( t o T i e n t ) != −1) | | ( e . gcd ( t o T i e n t ) .
compareTo ( B i g I n t e g e r . v a l u e O f ( 1 ) ) != 0 ) ) ;
// We found t h e v a l u e o f d . d = e ˆ1 mod t o T i e n t
d = e . modInverse ( t o T i e n t ) ;
c l a v e s = new ParDeClaves ( n , t o T i e n t , d , e ) ;
}
/∗ ∗
∗
∗ @return
∗/
p u b l i c B i g I n t e g e r getP ( ) {
return p ;
}
/∗ ∗
∗
∗ @return
∗/
p u b l i c B i g I n t e g e r getQ ( ) {
return q ;
}
/∗ ∗
∗
∗ @return
∗/
p u b l i c ParDeClaves g e t C l a v e s ( ) {
return claves ;
}
/∗ ∗
∗ Encrypts t h e AES key with t h e p r i v a t e key D
Annex A. Source Code 32
∗
∗ @param s e c r e t K e y
∗ @return
∗/
p u b l i c A r r a y L i s t <byte [] > c i f r a r C o n P r i v a d a ( byte [ ] s e c r e t K e y ) {
addDesc ( ” Clave en b y t e s : ” ) ;
addDesc ( M e t o d o s U t i l e s . enBytes ( s e c r e t K e y ) ) ;
l o n g s t a r t T i m e = System . nanoTime ( ) ;
B i g I n t e g e r [ ] numero = M e t o d o s U t i l e s . byteToInt ( s e c r e t K e y ) ;
addDesc ( ” Clave en e n t e r o s : ” ) ;
addDesc ( M e t o d o s U t i l e s . e n E n t e r o s ( numero ) ) ;
B i g I n t e g e r [ ] c i f r a d o = new B i g I n t e g e r [ numero . l e n g t h ] ;
addDesc ( ” C i f r a d o en e n t e r o s : ” ) ;
addDesc ( M e t o d o s U t i l e s . e n E n t e r o s ( c i f r a d o ) ) ;
r e t u r n M e t o d o s U t i l e s . intToByteArray ( c i f r a d o ) ;
}
/∗ ∗
∗ Encrypt t h e AES Key with t h e p u b l i c key E
∗
∗ @param s e c r e t K e y
∗ @return
∗/
p u b l i c A r r a y L i s t <byte [] > c i f r a r C o n P u b l i c a ( A r r a y L i s t <byte [] >
secretKey ) {
Annex A. Source Code 33
l o n g s t a r t T i m e = System . nanoTime ( ) ;
B i g I n t e g e r [ ] t e x t o = M e t o d o s U t i l e s . byteArrayToInt ( s e c r e t K e y ) ;
addDesc ( ” Clave en e n t e r o s : ” ) ;
addDesc ( M e t o d o s U t i l e s . e n E n t e r o s ( t e x t o ) ) ;
B i g I n t e g e r [ ] c i f r a d o = new B i g I n t e g e r [ t e x t o . l e n g t h ] ;
f o r ( i n t i = 0 ; i < t e x t o . l e n g t h ; i ++) {
C o n s t a n t e s . c o n t++;
c i f r a d o [ i ] = t e x t o [ i ] . modPow( c l a v e s . g e t P u b l i c a E ( ) . getE ( ) ,
c l a v e s . getN ( ) ) ;
}
l o n g end = System . nanoTime ( ) ;
l o n g elapsedTimeNs = System . nanoTime ( ) − s t a r t T i m e ;
System . out . p r i n t l n ( ” ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ” ) ;
System . out . p r i n t l n ( elapsedTimeNs + ” ns \n” ) ;
System . out . p r i n t l n ( ” ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ” ) ;
addDesc ( ” C i f r a d o en e n t e r o s : ” ) ;
addDesc ( M e t o d o s U t i l e s . e n E n t e r o s ( c i f r a d o ) ) ;
r e t u r n M e t o d o s U t i l e s . intToByteArray ( c i f r a d o ) ;
}
/∗ ∗
∗ Decrypts with t h e P r i v a t e D t o o b t a i n t h e AES 128 b i t key
∗
∗ @param c l a v e C i f r a d a 2
∗ @return
∗/
p u b l i c A r r a y L i s t <byte [] > d e c i f r a C o n P r i v a d a ( A r r a y L i s t <byte [] >
claveCifrada2 ) {
addDesc ( ” C i f r a d a 2 en b y t e s Array : ” ) ;
addDesc ( M e t o d o s U t i l e s . enByteArray ( c l a v e C i f r a d a 2 ) ) ;
l o n g s t a r t T i m e = System . nanoTime ( ) ;
B i g I n t e g e r [ ] c i f r a d a 2 = M e t o d o s U t i l e s . byteArrayToInt (
claveCifrada2 ) ;
addDesc ( ” C i f r a d a 2 en e n t e r o s : ” ) ;
Annex A. Source Code 34
addDesc ( M e t o d o s U t i l e s . e n E n t e r o s ( c i f r a d a 2 ) ) ;
System . out . p r i n t l n ( g e t D e s c ( ) ) ;
B i g I n t e g e r [ ] c i f r a d a = new B i g I n t e g e r [ c l a v e C i f r a d a 2 . s i z e ( ) ] ;
f o r ( i n t i = 0 ; i < c i f r a d a 2 . l e n g t h ; i ++) {
C o n s t a n t e s . c o n t++;
c i f r a d a [ i ] = c i f r a d a 2 [ i ] . modPow( c l a v e s . getPrivadaD ( ) . getD
( ) , c l a v e s . getN ( ) ) ;
}
r e t u r n M e t o d o s U t i l e s . intToByteArray ( c i f r a d a ) ;
}
/∗ ∗
∗ Decrypt with P u b l i c E , t o o b t a i n g t h e AES 128 b i t key .
∗
∗ @param c l a v e C i f r a d a
∗ @return
∗/
p u b l i c byte [ ] d e c i f r a C o n P u b l i c a ( A r r a y L i s t <byte [] > c l a v e C i f r a d a ) {
l o n g s t a r t T i m e = System . nanoTime ( ) ;
B i g I n t e g e r [ ] c i f r a d a = M e t o d o s U t i l e s . byteArrayToInt (
claveCifrada ) ;
addDesc ( ” C i f r a d a en e n t e r o s : ” ) ;
addDesc ( M e t o d o s U t i l e s . e n E n t e r o s ( c i f r a d a ) ) ;
B i g I n t e g e r [ ] s e c r e t K e y = new B i g I n t e g e r [ c l a v e C i f r a d a . s i z e ( ) ] ;
f o r ( i n t i = 0 ; i < c i f r a d a . l e n g t h ; i ++) {
C o n s t a n t e s . c o n t++;
Annex A. Source Code 35
s e c r e t K e y [ i ] = c i f r a d a [ i ] . modPow( c l a v e s . g e t P u b l i c a E ( ) .
getE ( ) , c l a v e s . getN ( ) ) ;
}
addDesc ( ” D e c i f r a d o en e n t e r o s : ” ) ;
addDesc ( M e t o d o s U t i l e s . e n E n t e r o s ( s e c r e t K e y ) ) ;
byte [ ] t e x t o = M e t o d o s U t i l e s . intToByte ( s e c r e t K e y ) ;
addDesc ( ” D e c i f r a d o en b y t e s : ” ) ;
addDesc ( M e t o d o s U t i l e s . enBytes ( t e x t o ) ) ;
return texto ;
}
p u b l i c S t r i ng getDesc ( ) {
return desc ;
}
p u b l i c v o i d addDesc ( S t r i n g s ) {
t h i s . d e s c += s ;
}
}
The class ClavePrivada.java is used for generating RSA private key algorithm.
package l o g i c a . r s a ;
import j a v a . math . B i g I n t e g e r ;
/∗ ∗
∗ G e n e r a t i n g RSA p r i v a t e key a l g o r i t h m
∗
∗ @author L u i s H Santamaria
∗/
p u b l i c c l a s s Cl av e Pr iv ad a {
Annex A. Source Code 36
private BigInteger d ;
p u b l i c Cl av eP r iv ad a ( B i g I n t e g e r d ) {
this .d = d;
}
p u b l i c B i g I n t e g e r getD ( ) {
return d ;
}
p u b l i c byte [ ] getEncoded ( ) {
r e t u r n d . toByteArray ( ) ;
}
}
The class ClavePublica.java is used for generating RSA public key algorithm.
package l o g i c a . r s a ;
import j a v a . math . B i g I n t e g e r ;
/∗ ∗
∗ G e n e r a t i n g RSA p u b l i c key a l g o r i t h m
∗ @author L u i s H Santamaria
∗/
public c l a s s ClavePublica {
private BigInteger e ;
p u b l i c B i g I n t e g e r getE ( ) {
return e ;
}
p u b l i c byte [ ] getEncoded ( ) {
r e t u r n e . toByteArray ( ) ;
}
}
package l o g i c a . r s a ;
import j a v a . math . B i g I n t e g e r ;
/∗ ∗
∗ C o n t a i n s p r i v a t e and p u b l i c key o f RSA a l g o r i t h m
∗
∗ @author L u i s H Santamaria
∗/
p u b l i c c l a s s ParDeClaves {
private f i n a l BigInteger n ;
private f i n a l BigInteger toTient ;
p r i v a t e C la ve P ri va da privadaD ;
p r i v a t e ClavePublica publicaE ;
p u b l i c ParDeClaves ( B i g I n t e g e r n , B i g I n t e g e r t o T i e n t , B i g I n t e g e r
privadaD , B i g I n t e g e r p u b l i c a E ) {
this .n = n;
t h i s . toTient = toTient ;
t h i s . privadaD = new C la ve P ri va da ( privadaD ) ;
t h i s . p u b l i c a E = new C l a v e P u b l i c a ( p u b l i c a E ) ;
privadaD . toByteArray ( ) ;
}
p u b l i c B i g I n t e g e r getN ( ) {
return n ;
}
p u b l i c B i g I n t e g e r getToTient ( ) {
return toTient ;
}
p u b l i c Cl av eP r iv ad a getPrivadaD ( ) {
Annex A. Source Code 38
r e t u r n privadaD ;
}
p u b l i c v o i d setPrivadaD ( C l av eP ri v ad a privadaD ) {
t h i s . privadaD = privadaD ;
}
The AES.java class is responsible for implementing all the logic of the AES algo-
rithm. The Package javax.crypto is used which provides the classes and interfaces
for cryptographic operations. We make use of Cipher and SecretKeySpec JAVA
classes to encrypt and decrypt with AES.
package l o g i c a . a e s ;
import j a v a . s e c u r i t y . I n v a l i d K e y E x c e p t i o n ;
import j a v a . s e c u r i t y . NoSuchAlgorithmException ;
import j a v a x . c r y p t o . BadPaddingException ;
import j a v a x . c r y p t o . Cipher ;
import j a v a x . c r y p t o . I l l e g a l B l o c k S i z e E x c e p t i o n ;
import j a v a x . c r y p t o . KeyGenerator ;
import j a v a x . c r y p t o . NoSuchPaddingException ;
import j a v a x . c r y p t o . s p e c . SecretKeySpec ;
import l o g i c a . n u c l e o . e n t i d a d e s . Mensaje ;
import l o g i c a . u t i l . C o n s t a n t e s ;
import l o g i c a . u t i l . M e t o d o s U t i l e s ;
/∗ ∗
∗
∗ @author L u i s H Santamaria
∗/
p u b l i c c l a s s AES {
p r i v a t e byte [ ] c l a v e ;
Annex A. Source Code 39
/∗ ∗
∗
∗ @param n
∗/
p u b l i c AES( i n t n ) {
}
/∗ ∗
∗
∗ @throws E x c e p t i o n
∗/
p u b l i c AES( ) throws E x c e p t i o n {
generarClave () ;
}
/∗ ∗
∗ G e n e r a t e s t h e AES 128− b i t Key
∗
∗ @throws E x c e p t i o n
∗/
p r i v a t e v o i d g e n e r a r C l a v e ( ) throws E x c e p t i o n {
try {
KeyGenerator kgen = KeyGenerator . g e t I n s t a n c e ( C o n s t a n t e s .
ALGORITMO AES) ;
kgen . i n i t ( C o n s t a n t e s . LONGITUD CLAVE AES) ;
c l a v e = M e t o d o s U t i l e s . e l i m i n a r N e g a t i v o s ( kgen . generateKey
( ) . getEncoded ( ) ) ;
} c a t c h ( NoSuchAlgorithmException ex ) {
throw new E x c e p t i o n ( ” NoSuchAlgorithmException − E r r o r en
l a g e n e r a c i o n de l a c l a v e AES − ” + ex . getMessage ( ) ) ;
}
}
/∗ ∗
∗ Leave t h e key empty
∗/
public void limpiarClave ( ) {
c l a v e = new byte [ 0 ] ;
}
/∗ ∗
∗ Encrypt t h e message t o send
∗
Annex A. Source Code 40
∗ @param t e x t o A C i f r a r
∗ @throws E x c e p t i o n
∗/
p u b l i c v o i d c i f r a r ( Mensaje t e x t o A C i f r a r ) throws E x c e p t i o n {
try {
byte [ ] raw = g e t C l a v e ( ) ;
SecretKeySpec s k e y S p e c = new SecretKeySpec ( raw ,
C o n s t a n t e s .ALGORITMO AES) ; // C r e a t e an i n s t a n c e o f t h e c l a s s
SecretKeySpec j a v a and a s s o c i a t e s t o t h e a l g o r i t h m .
Cipher c i p h e r = Cipher . g e t I n s t a n c e ( C o n s t a n t e s .
ALGORITMO AES) ; // This c l a s s i s r e s p o n s i b l e f o r e n c r y p t i n g and
d e c r y p t i n g with AES
c i p h e r . i n i t ( Cipher .ENCRYPT MODE, s k e y S p e c ) ; // Encrypt mode
is selected
byte [ ] e n c r y p t e d = c i p h e r . d o F i n a l ( t e x t o A C i f r a r .
g e t M e n s a j e C l a r o B y t e ( ) ) ; //RETURN THE RESULT: S e t t l e m e n t o f b y t e s
encrypted
textoACifrar . setMensajeCifradoByte ( encrypted ) ;
} c a t c h ( NoSuchAlgorithmException ex ) {
throw new E x c e p t i o n ( ” NoSuchAlgorithmException ” + ex .
getMessage ( ) ) ;
} c a t c h ( NoSuchPaddingException ex ) {
throw new E x c e p t i o n ( ” NoSuchPaddingException ” + ex .
getMessage ( ) ) ;
} c a t c h ( I n v a l i d K e y E x c e p t i o n ex ) {
throw new E x c e p t i o n ( ” I n v a l i d K e y E x c e p t i o n ” + ex .
getMessage ( ) ) ;
} c a t c h ( I l l e g a l B l o c k S i z e E x c e p t i o n ex ) {
throw new E x c e p t i o n ( ” I l l e g a l B l o c k S i z e E x c e p t i o n ” + ex .
getMessage ( ) ) ;
} c a t c h ( BadPaddingException ex ) {
throw new E x c e p t i o n ( ” BadPaddingException ” + ex .
getMessage ( ) ) ;
}
/∗ ∗
∗ Decrypts t h e message with an 128− b i t AES key
∗
∗ @param t e x t o A D e c i f r a r
∗ @throws NoSuchAlgorithmException
∗ @throws NoSuchPaddingException
Annex A. Source Code 41
∗ @throws I n v a l i d K e y E x c e p t i o n
∗ @throws I l l e g a l B l o c k S i z e E x c e p t i o n
∗ @throws BadPaddingException
∗/
p u b l i c v o i d d e c i f r a r ( Mensaje t e x t o A D e c i f r a r ) throws
NoSuchAlgorithmException , NoSuchPaddingException ,
InvalidKeyException , I l l e g a l B l o c k S i z e E x c e p t i o n ,
BadPaddingException {
byte [ ] raw = g e t C l a v e ( ) ;
SecretKeySpec s k e y S p e c = new SecretKeySpec ( raw , C o n s t a n t e s .
ALGORITMO AES) ; // C r e a t e an i n s t a n c e o f t h e c l a s s SecretKeySpec
j a v a and a s s o c i a t e s t o t h e a l g o r i t h m .
Cipher c i p h e r = Cipher . g e t I n s t a n c e ( C o n s t a n t e s .ALGORITMO AES) ;
// This c l a s s i s r e s p o n s i b l e f o r e n c r y p t i n g and d e c r y p t i n g with AES
c i p h e r . i n i t ( Cipher .DECRYPT MODE, s k e y S p e c ) ; // Decrypt mode i s
selected
byte [ ] d e c i f r a d o = c i p h e r . d o F i n a l ( t e x t o A D e c i f r a r .
g e t M e n s a j e C i f r a d o B y t e ( ) ) ; //RETURN THE RESULT: S e t t l e m e n t o f b y t e s
decrypted
textoADecifrar . setMensajeClaroByte ( d e c i f r a d o ) ;
}
/∗ ∗
∗
∗ @param c l a v e
∗/
p u b l i c v o i d s e t C l a v e ( byte [ ] c l a v e ) {
this . clave = clave ;
}
/∗ ∗
∗
∗ @return
∗/
p u b l i c byte [ ] g e t C l a v e ( ) {
i f ( c l a v e == n u l l ) {
r e t u r n new byte [ 0 ] ;
}
return clave ;
}
}
Annex A. Source Code 42
CifradoAES RSA.java contains all the application logic. All methods for sending
and receiving operation with RSA (twice) and AES.
package l o g i c a . n u c l e o . e n t i d a d e s ;
import j a v a . u t i l . A r r a y L i s t ;
/∗ ∗
∗
∗ @author L u i s H Santamaria
∗/
p u b l i c c l a s s CifradoAES RSA {
p r i v a t e Parametros p a r a m e t r o s ;
p u b l i c CifradoAES RSA ( C l a v e s R e c e p t o r r e c e p t o r ) {
p a r a m e t r o s = new Parametros ( ) ;
parametros . i n i c i a l i z a r P a r a m e t r o s ( r e c e p t o r ) ;
}
s += ”−−−−−−−−−−−−−−−−−−−\n” ;
s += ” C i f r a r con P u b l i c a B\n” ;
cifrarConPublica B () ;
s += g e t P a r a m e t r o s ( ) . getRsa ParB ( ) . g e t D e s c ( ) ;
return s ;
}
decifraConPublica A () ;
s += g e t P a r a m e t r o s ( ) . getRsa ParA ( ) . g e t D e s c ( ) ;
return s ;
}
/∗ ∗
∗ Encrypt with AES
∗
∗ @throws E x c e p t i o n
∗/
p u b l i c v o i d c i f r a r A E S ( ) throws E x c e p t i o n {
p a r a m e t r o s . getAes ( ) . c i f r a r ( p a r a m e t r o s . g e t M e n s a j e ( ) ) ;
}
/∗ ∗
∗ Decrypt with AES
∗
∗ @throws E x c e p t i o n
∗/
p u b l i c v o i d d e c i f r a r A E S ( ) throws E x c e p t i o n {
p a r a m e t r o s . getAes ( ) . d e c i f r a r ( p a r a m e t r o s . g e t M e n s a j e ( ) ) ;
}
/∗ ∗
∗
∗/
public void cifrarConPrivada A ( ) {
byte [ ] c l a v e = p a r a m e t r o s . getAes ( ) . g e t C l a v e ( ) ;
A r r a y L i s t <byte [] > c l a v e C i f r a d a = p a r a m e t r o s . getRsa ParA ( ) .
cifrarConPrivada ( clave ) ;
System . out . p r i n t l n ( ” Clave c i f r a d a ” ) ;
System . out . p r i n t l n ( p a r a m e t r o s . getRsa ParA ( ) . g e t D e s c ( ) ) ;
mostrar ( c l a v e C i f r a d a ) ;
parametros . getMensaje ( ) . setClaveCifrada ( c l a v e C i f r a d a ) ;
}
/∗ ∗
∗
∗/
public void cifrarConPublica B ( ) {
A r r a y L i s t <byte [] > c l a v e C i f r a d a = p a r a m e t r o s . g e t M e n s a j e ( ) .
getClaveCifrada () ;
A r r a y L i s t <byte [] > c l a v e C i f r a d a 2 = p a r a m e t r o s . getRsa ParB ( ) .
cifrarConPublica ( claveCifrada ) ;
Annex A. Source Code 44
/∗ ∗
∗
∗/
public void decifraConPrivada B ( ) {
A r r a y L i s t <byte [] > c l a v e C i f r a d a 2 = p a r a m e t r o s . g e t M e n s a j e ( ) .
getClaveCifrada () ;
A r r a y L i s t <byte [] > c l a v e C i f r a d a = p a r a m e t r o s . getRsa ParB ( ) .
decifraConPrivada ( claveCifrada2 ) ;
System . out . p r i n t l n ( ” Clave c i f r a d a ” ) ;
System . out . p r i n t l n ( p a r a m e t r o s . getRsa ParB ( ) . g e t D e s c ( ) ) ;
mostrar ( c l a v e C i f r a d a ) ;
parametros . getMensaje ( ) . setClaveCifrada ( c l a v e C i f r a d a ) ;
}
/∗ ∗
∗
∗/
public void decifraConPublica A ( ) {
A r r a y L i s t <byte [] > c l a v e C i f r a d a = p a r a m e t r o s . g e t M e n s a j e ( ) .
getClaveCifrada () ;
byte [ ] c l a v e = p a r a m e t r o s . getRsa ParA ( ) . d e c i f r a C o n P u b l i c a (
claveCifrada ) ;
System . out . p r i n t l n ( ” Clave c i f r a d a ” ) ;
System . out . p r i n t l n ( p a r a m e t r o s . getRsa ParB ( ) . g e t D e s c ( ) ) ;
mostrar ( c l a v e C i f r a d a ) ;
p a r a m e t r o s . getAes ( ) . s e t C l a v e ( c l a v e ) ;
}
/∗ ∗
∗
∗ @return
∗/
p u b l i c Parametros g e t P a r a m e t r o s ( ) {
r e t u r n pa r a m e t r o s ;
}
/∗ ∗
∗
Annex A. Source Code 45
∗/
p u b l i c void limpiarParametrosA ( ) {
g e t P a r a m e t r o s ( ) . getAes ( ) . l i m p i a r C l a v e ( ) ;
getParametros ( ) . getMensaje ( ) . limpiarMensajeCl ( ) ;
}
/∗ ∗
∗
∗ @param a r r a y
∗/
p r i v a t e v o i d m o s t r a r ( A r r a y L i s t <byte [] > a r r a y ) {
f o r ( byte [ ] bs : a r r a y ) {
f o r ( byte b : bs ) {
System . out . p r i n t ( b + ” ” ) ;
}
System . out . p r i n t ( ” | ” ) ;
}
}
}
In ClavesReceptor.java we can find the keys retrieved from the trusted database,
for the message that recipient wants to decipher.
package l o g i c a . n u c l e o . e n t i d a d e s ;
import j a v a . math . B i g I n t e g e r ;
import j a v a . u t i l . A r r a y L i s t ;
/∗ ∗
∗
∗ @author L u i s H Santamaria
∗/
public c l a s s ClavesReceptor {
p r i v a t e A r r a y L i s t <byte [] > c l a v e C i f ;
p r i v a t e byte [ ] m e n s a j e C i f r a d o B y t e ;
private BigInteger aPublica ;
p r i v a t e B i g I n t e g e r aPrivada ;
p r i v a t e BigInteger bPublica ;
p r i v a t e B i g I n t e g e r bPrivada ;
p r i v a t e B i g I n t e g e r aN ;
p r i v a t e B i g I n t e g e r bN ;
Annex A. Source Code 46
p u b l i c B i g I n t e g e r getaN ( ) {
r e t u r n aN ;
}
p u b l i c v o i d setaN ( B i g I n t e g e r aN) {
t h i s . aN = aN ;
}
p u b l i c B i g I n t e g e r getbN ( ) {
r e t u r n bN ;
}
p u b l i c v o i d setbN ( B i g I n t e g e r bN) {
t h i s . bN = bN ;
}
p u b l i c A r r a y L i s t <byte [] > g e t C l a v e ( ) {
return claveCif ;
}
p u b l i c v o i d s e t C l a v e ( A r r a y L i s t <byte [] > c l a v e ) {
this . claveCif = clave ;
}
p u b l i c byte [ ] g e t M e n s a j e C i f r a d o B y t e ( ) {
return mensajeCifradoByte ;
}
p u b l i c v o i d s e t M e n s a j e C i f r a d o B y t e ( byte [ ] m e n s a j e C i f r a d o B y t e ) {
t h i s . mensajeCifradoByte = mensajeCifradoByte ;
Annex A. Source Code 47
p u b l i c v o i d s e t a P r i v a d a ( B i g I n t e g e r aPrivada ) {
t h i s . aPrivada = aPrivada ;
}
p u b l i c v o i d s e t b P r i v a d a ( B i g I n t e g e r bPrivada ) {
t h i s . bPrivada = bPrivada ;
}
}
Token.java class represents the security token application using a USB device.
package l o g i c a . token ;
import j a v a . i o . B u f f e r e d R e a d e r ;
import j a v a . i o . F i l e R e a d e r ;
import j a v a . i o . F i l e ;
import j a v a . i o . F i l e n a m e F i l t e r ;
import j a v a . i o . IOException ;
Annex A. Source Code 48
import j a v a . u t i l . NoSuchElementException ;
import j a v a . u t i l . S t r i n g T o k e n i z e r ;
/∗ ∗
∗
∗ @author L u i s H Santamaria
∗/
p u b l i c c l a s s Token {
p r i v a t e s t a t i c F i l e URL;
p r i v a t e s t a t i c S t r i n g Email , Password , Names ;
p r i v a t e s t a t i c S t r i n g Descr ;
// v a l i d a s i s e e n c u e n t r a e l token
p u b l i c Token ( ) throws E x c e p t i o n {
do {
w h i l e (URL == n u l l ) {
URL = BuscarToken ( ) ;
}
} w h i l e ( ! ValidarToken ( ) ) ;
p u b l i c S t r i n g g e tE m ai l ( ) {
r e t u r n Email ;
// V e r i f i e s t h a t t h e Token i s t h e r e
p u b l i c v o i d v e r i f i c a T o k e n ( ) throws E x c e p t i o n {
F i l e u r l 2 = BuscarToken ( ) ;
i f ( u r l 2 != n u l l ) {
i f ( ! ValidarToken ( ) ) {
throw new E x c e p t i o n ( ” El token no e s v a l i d o ” ) ;
}
} else {
Annex A. Source Code 49
p u b l i c S t r i n g getPassword ( ) {
r e t u r n Password ;
}
p u b l i c S t r i n g getNames ( ) {
r e t u r n Names ;
BufferedReader brtk = n u l l ;
try {
String line ;
w h i l e ( ( l i n e = b r t k . r e a d L i n e ( ) ) != n u l l ) {
S t r i n g T o k e n i z e r LineaToken = new S t r i n g T o k e n i z e r ( l i n e
, ” | ”) ;
try {
Email = LineaToken . nextElement ( ) . t o S t r i n g ( ) ;
Password = LineaToken . nextElement ( ) . t o S t r i n g
() ;
Names = LineaToken . nextElement ( ) . t o S t r i n g ( ) ;
} c a t c h ( NoSuchElementException eq ) {
S t r i n g e r r o r = ”Token I n v a l i d o \n” + ” E j e c u t e
de nuevo l a a p l i c a c i o n con un Token V a l i d o \n”
+ eq . getMessage ( ) ;
throw new E x c e p t i o n ( e r r o r ) ;
}
Annex A. Source Code 50
}
}
} c a t c h ( IOException e ) {
throw e ;
} finally {
try {
i f ( b r t k != n u l l ) {
brtk . c l o s e ( ) ;
}
} c a t c h ( IOException ex ) {
throw ex ;
}
}
// Looks f o r t h e . tk f i l e i n s i d e o f t h e USB
p u b l i c s t a t i c F i l e BuscarToken ( ) {
F i l e unidades [ ] = F i l e . l i s t R o o t s ( ) , f i l e s [ ] = n u l l ;
f o r ( i n t i = 0 ; i < u n i d a d e s . l e n g t h ; i ++) {
// addDesc ( u n i d a d e s [ i ] ) ;
f o r ( i n t i = 0 ; i < u n i d a d e s . l e n g t h ; i ++) {
f i l e s = u n i d a d e s [ i ] . l i s t F i l e s ( new F i l e n a m e F i l t e r ( ) {
p u b l i c b o o l e a n a c c e p t ( F i l e d i r , S t r i n g name ) {
r e t u r n name . toLowerCase ( ) . endsWith ( ” . tk ” ) ;
}
}) ;
}
i f ( f i l e s == n u l l ) {
return null ;
}
return f i l e s [ 0 ] ;
p r i v a t e v o i d addDesc ( S t r i n g message ) {
Descr += message ;
}
}
import g u i . A d m i n i s t r a d o r ;
import s t a t i c j a v a . l a n g . Thread . s l e e p ;
import j a v a . u t i l . l o g g i n g . L e v e l ;
import j a v a . u t i l . l o g g i n g . Logger ;
/∗ ∗
∗
∗ @author L u i s H Santamaria
∗/
p u b l i c c l a s s H i l o V e r i f i c a T o k e n e x t e n d s Thread {
A d m i n i s t r a d o r admin ;
p u b l i c H i l o V e r i f i c a T o k e n ( A d m i n i s t r a d o r admin ) {
t h i s . admin = admin ;
}
Annex A. Source Code 52
p u b l i c v o i d run ( ) {
try {
do {
try {
admin . getToken ( ) . v e r i f i c a T o k e n ( ) ;
} c a t c h ( E x c e p t i o n ex ) {
Logger . g e t L o g g e r ( H i l o V e r i f i c a T o k e n . c l a s s . getName
( ) ) . l o g ( L e v e l . SEVERE, n u l l , ex ) ;
System . e x i t ( 0 ) ;
}
s l e e p ( 1 ∗ 1 0 0 0 ) ; // The t h r e a d i s s l e e p f o r 30 s e c o n d s
} while ( true ) ;
} c a t c h ( I n t e r r u p t e d E x c e p t i o n ex ) {
Logger . g e t L o g g e r ( H i l o V e r i f i c a T o k e n . c l a s s . getName ( ) ) . l o g (
L e v e l . SEVERE, n u l l , ex ) ;
}
}
}
The Mail.java class represents an electronic email. It make uses of the Java.Mail
Package which provides a platform-independent and protocol-independent frame-
work to build mail and messaging applications.
package l o g i c a . m a i l . c l i e n t . l i b s ;
import j a v a x . m a i l . Address ;
import j a v a x . m a i l . Message ;
import j a v a x . m a i l . M e s s a g i n g E x c e p t i o n ;
import j a v a x . m a i l . S e s s i o n ;
import j a v a x . m a i l . i n t e r n e t . A d d r e s s E x c e p t i o n ;
import j a v a x . m a i l . i n t e r n e t . I n t e r n e t A d d r e s s ;
import j a v a x . m a i l . i n t e r n e t . MimeMessage ;
import l o g i c a . u t i l . C o n s t a n t e s ;
/∗ ∗
∗
∗ @author L u i s H Santamaria
∗/
p u b l i c c l a s s Mail {
p r i v a t e s t a t i c i n t Id ;
p r i v a t e s t a t i c i n t Id Bd ;
p r i v a t e s t a t i c S t r i n g Asunto , Mensaje , C i f r a d o ;
p r i v a t e s t a t i c Address [ ] De , Para ;
Annex A. Source Code 53
try {
De = AFrom ;
Para = ATo ;
Asunto = S u b j e c t ;
Id Bd = 0 ;
Mensaje = Body ;
Cifrado = encript ;
} catch ( AddressException e ) {
}
Id = Number ;
De = From ;
Para = To ;
Asunto = S u b j e c t ;
Id Bd = −1;
Mensaje = Body . t o S t r i n g ( ) ;
Cifrado = null ;
Id = Number ;
Annex A. Source Code 54
De = From ;
Para = To ;
try {
String tokens [ ] = Subject . s p l i t ( Constantes .
SEPARADOR ASUNTO) ;
Asunto = t o k e n s [ 0 ] ;
Id Bd = I n t e g e r . p a r s e I n t ( t o k e n s [ 1 ] ) ;
} catch ( Exception e ) {
System . out . p r i n t l n ( ” R e v i s e e l Asunto d e l Mensaje ” + e .
getMessage ( ) ) ;
}
Mensaje = Body . t o S t r i n g ( ) ;
Cifrado = null ;
p u b l i c Message MailtoSend ( S e s s i o n s e s i o n ) {
// Function t o r e t r i e v e m a i l s e n t
try {
mensaje . setFrom ( De [ 0 ] ) ;
} catch ( MessagingException e ) {
throw new RuntimeException ( e ) ;
}
r e t u r n mensaje ;
Annex A. Source Code 55
@Override
public String toString () {
S t r i n g B u i l d e r sb = new S t r i n g B u i l d e r ( ) ;
r e t u r n sb . t o S t r i n g ( ) ;
}
/∗ ∗
∗
∗ @return
∗/
public I n t e g e r getIdMensaje ( ) {
r e t u r n Id Bd ;
}
p u b l i c S t r i n g getMensaje ( ) {
r e t u r n Mensaje ;
}
p u b l i c s t a t i c S t r i n g getAsunto ( ) {
r e t u r n Asunto ;
}
p u b l i c v o i d s e t I d B d ( i n t Id Bd ) {
Mail . Id Bd = Id Bd ;
}
p u b l i c v o i d s e t A s u n t o ( S t r i n g Asunto ) {
Mail . Asunto = Asunto ;
}
}
Annex A. Source Code 56
MetodosUtiles.java is a class that implements the most used methods in the ap-
plication for different classes.
package l o g i c a . u t i l ;
import j a v a . math . B i g I n t e g e r ;
import j a v a . u t i l . A r r a y L i s t ;
import l o g i c a . n u c l e o . e n t i d a d e s . C l a v e s R e c e p t o r ;
import p e r s i s t e n c i a . e n t i t i e s . Clave ;
/∗ ∗
∗
∗ @author L u i s H Santamaria
∗/
public c l a s s MetodosUtiles {
/∗ ∗
∗ Get an a r r a y o f bytes , each byte and c o n v e r t s i t t o an i n t e g e r
and
∗ i n t e g e r t o a hex . Then r e t u r n s a l l hexa i n a t e x t . Converts
t h e byte i n
∗ hexadecimal .
∗
∗ @param a r r e g l o E n c r i p t a d o
∗ @return
∗/
p u b l i c s t a t i c S t r i n g bytesToHexa ( byte [ ] a r r e g l o E n c r i p t a d o ) {
S t r i n g textoEncriptado = ”” ;
f o r ( i n t i = 0 ; i < a r r e g l o E n c r i p t a d o . l e n g t h ; i ++) {
i n t aux = a r r e g l o E n c r i p t a d o [ i ] & 0 x f f ;
i f ( aux < 1 6 ) {
textoEncriptado = textoEncriptado . concat ( ”0” ) ;
}
textoEncriptado = textoEncriptado . concat ( Integer .
t o H e x S t r i n g ( aux ) ) ;
}
return textoEncriptado ;
}
/∗ ∗
∗ R e c e i v e a t e x t with s e v e r a l h e x a d e c i m a l . Then i t remove and
convert into
Annex A. Source Code 57
p u b l i c s t a t i c B i g I n t e g e r [ ] byteToInt ( byte [ ] b y t e s ) {
// b y t e s [ 0 ] .
// B i g I n t e g e r b = new B i g I n t e g e r (””+)
B i g I n t e g e r [ ] e n t e r o s = new B i g I n t e g e r [ b y t e s . l e n g t h ] ;
f o r ( i n t i = 0 ; i < b y t e s . l e n g t h ; i ++) {
byte [ ] b = new byte [ 1 ] ;
b [ 0 ] = bytes [ i ] ;
e n t e r o s [ i ] = new B i g I n t e g e r ( b ) ;
}
return enteros ;
}
p u b l i c s t a t i c byte [ ] intToByte ( B i g I n t e g e r [ ] e n t e r o s ) {
Annex A. Source Code 58
f o r ( i n t i = 0 ; i < b y t e s . l e n g t h ; i ++) {
b y t e s [ i ] = e n t e r o s [ i ] . byteValue ( ) ;
}
return bytes ;
}
f o r ( i n t i = 0 ; i < e n t e r o s . l e n g t h ; i ++) {
byte [ ] ba = e n t e r o s [ i ] . toByteArray ( ) ;
b y t e s . add ( ba ) ;
}
return bytes ;
}
p u b l i c s t a t i c byte [ ] e l i m i n a r N e g a t i v o s ( byte [ ] b y t e s ) {
f o r ( i n t i = 0 ; i < b y t e s . l e n g t h ; i ++) {
i f ( Byte . v a l u e O f ( b y t e s [ i ] ) . compareTo ( Byte . v a l u e O f ( ” 0 ” ) ) <
0 ) { // s i e s n e g a t i v o
i n t pos = Byte . v a l u e O f ( b y t e s [ i ] ) . i n t V a l u e ( ) ∗ ( −1) ;
b y t e s [ i ] = Byte . v a l u e O f ( ” ” + pos ) ;
}
}
return bytes ;
}
p u b l i c s t a t i c S t r i n g enBytes ( byte [ ] b y t e s ) {
Annex A. Source Code 59
S t r i n g s = ”” ;
f o r ( byte b : b y t e s ) {
s += b + ” ” ;
}
s += ” \n” ;
return s ;
}
p u b l i c s t a t i c C l a v e s R e c e p t o r c o n v e r t i r C l a v e R e c ( Clave c l a v e ,
S t r i n g menCifrado ) {
A r r a y L i s t <byte [] > c l a v e c i f = String ToBytes Array ( c l a v e .
getAesCif () ) ;
byte [ ] m e n s a j e C i f r a d o B y t e = hexaToBytes ( menCifrado . t r i m ( ) ) ;
B i g I n t e g e r a P u b l i c a = new B i g I n t e g e r ( hexaToBytes ( c l a v e .
getAPublica ( ) ) ) ;
B i g I n t e g e r aPrivada = new B i g I n t e g e r ( hexaToBytes ( c l a v e .
getAPrivada ( ) ) ) ;
B i g I n t e g e r b P u b l i c a = new B i g I n t e g e r ( hexaToBytes ( c l a v e .
getBPublica ( ) ) ) ;
B i g I n t e g e r bPrivada = new B i g I n t e g e r ( hexaToBytes ( c l a v e .
getBPrivada ( ) ) ) ;
B i g I n t e g e r an = new B i g I n t e g e r ( hexaToBytes ( c l a v e . getAN ( ) ) ) ;
B i g I n t e g e r bn = new B i g I n t e g e r ( hexaToBytes ( c l a v e . getBN ( ) ) ) ;
Annex A. Source Code 60
r e t u r n new C l a v e s R e c e p t o r ( c l a v e c i f , m e n s a j e C i f r a d o B y t e ,
a P u b l i c a , aPrivada , bPublica , bPrivada , an , bn ) ;
}
}