I have made a post about message digest and secret key before. Now we will see how to generate a message digest using a secret key in Java.
First, we created the message and convert it to array of byte.
Then, we created a KeyGenerator object, the object that will generate our secret key, by supplying an algorithm name. In this case we use AES to generate the secret key. Note that we can also create s secret key using a secret key string as we did in this post.
Next, we created a Mac object. Message Authentication Code (MAC) is a Message Digest that is generated using a secret key. There are several algorithms available for Mac. For now we choose HmacMD5. Note that the secret key and mac algorithms are completely separated, for example we use AES for secret key generation and HmacMD5 for Mac.
Then we initialize Mac with our secret key object and then update it with our original message.
We then call doFinal() method of Mac object against our original message to generate the message digest byte. Converting the byte to String using UTF8 encoding enables us to display the generated message digest to console as shown below.
Monday, April 28, 2014
Sunday, April 27, 2014
Asymmetric Encryption in Java
Asymmetric encryption uses a pair of public and private key to encrypt and decrypt messages. A message that is encrypted using a public or private key can only be decrypted using the other corresponding private or public key. RSA is an algorithm that is widely used to generate public and private key pair. RSA allows us to define how long the key is, 1024, 2048, or 4096 bits. Let's now try how to implement asymmetric encryption in Java.
Then, we created a KeyPairGenerator object that will generate a pair of public-private key for us. We passed RSA, the algorithm name that will be used to generate the keys and then initialized it with the key size of 2048 bits. We can also initialize it with key size of 1024 or 4096 bits depending on our need. One thing to note is the longer the key, the longer it takes to generate the public-private key.
In the code above, we obtain the public and private key objects. Usually, the keys are then serialized to a file so that it can be read later to encrypt or decrypt messages.
Next, we created a Cipher object by passing, what javadoc refers as, a transformation. It is a string that describes the operations to be performed on the given input to produce some output. There are several transformation strings we can choose depending on the algorithm we use. Since in this case we use RSA, we use RSA/ECB/PKCS1Padding. We can use other transformation string of our preference.
Then we initialize the Cipher object by passing it the public key object we created before and a flag to tell the Cipher that we want to do encryption as stated on ENCRYPT_MODE.
After everything is ready, we called doFinal() on Cipher object to start the encryption. The result is shown below:
After successfully encrypting the message now we will try to decrypt it. The code below shows how we do this by simply passing the private key and a flag indicating that now we are interested in decrypting a text instead of encrypting it.
The decryption happens when we call doFinal() on Cipher object as we did when encrypting message.
The decryption result is shown below:
First, we define the message that we want to encrypt and convert it to array of byte.
Then, we created a KeyPairGenerator object that will generate a pair of public-private key for us. We passed RSA, the algorithm name that will be used to generate the keys and then initialized it with the key size of 2048 bits. We can also initialize it with key size of 1024 or 4096 bits depending on our need. One thing to note is the longer the key, the longer it takes to generate the public-private key.
In the code above, we obtain the public and private key objects. Usually, the keys are then serialized to a file so that it can be read later to encrypt or decrypt messages.
Next, we created a Cipher object by passing, what javadoc refers as, a transformation. It is a string that describes the operations to be performed on the given input to produce some output. There are several transformation strings we can choose depending on the algorithm we use. Since in this case we use RSA, we use RSA/ECB/PKCS1Padding. We can use other transformation string of our preference.
Then we initialize the Cipher object by passing it the public key object we created before and a flag to tell the Cipher that we want to do encryption as stated on ENCRYPT_MODE.
After everything is ready, we called doFinal() on Cipher object to start the encryption. The result is shown below:
After successfully encrypting the message now we will try to decrypt it. The code below shows how we do this by simply passing the private key and a flag indicating that now we are interested in decrypting a text instead of encrypting it.
The decryption happens when we call doFinal() on Cipher object as we did when encrypting message.
The decryption result is shown below:
Symmetric Encryption in Java
Symmetric encryption uses a secret key (also known as private key) to encrypt and decrypt messages. Data Encryption Standard (DES) is an algorithm that is widely used to generate secret key. Other algorithms are AES and DEDede.
Session key is a term that is used to represent a secret key that its lifetime is limited. For example a secret key that is generated to encrypt a digital conversation. The key is destroyed after the conversation is finished. DES allows us to use 8 characters string as a key while AES allows 16 characters key and DESede allows 24 characters key. Let's try to encrypt and decrypt string in Java.
First we define our secret key string. Since we want to try AES, we have a 16 characters string as the secret key. We also created the message and convert it to an array of byte.
Next we created a SecretKey object by passing our secret key and the algorithm name of our preference. In this case we passed AES and its 16 bytes secret key.
Next we created a Cipher object by passing, what Javadoc refers as, a transformation. It is a string that describes the operations to be performed on the given input to produce some output. There are several transformation strings we can choose depending on the algorithm we use. Since in this case we use AES, we use AES/ECB/PKCS5Padding. We can use other transformation string of our preference.
Then we initialize the Cipher object by passing it the secret key object we created before and a flag to tell the Cipher that we want to do encryption as stated on ENCRYPT_MODE.
Now we can start encryption by calling doFinal() on the Cipher object as we did above. The encrypted text is show below:
After successfully encrypting the message now we will try to decrypt it. The code below shows how we do it by simply passing the secret key and a flag indicating that now we are interested in decrypting a text instead of encrypting it.
The decryption happens when we call doFinal() on Cipher object as we did when encrypting message.
The decryption result is shown below:
Instead of providing a string of secret key, Java provides us a secret key generator class named KeyGenerator. Our code below shows how we can take advantage of this class to generate a random secret key:
KeyGenerator takes algorithm name as a parameter to generate the secret key for us.
Session key is a term that is used to represent a secret key that its lifetime is limited. For example a secret key that is generated to encrypt a digital conversation. The key is destroyed after the conversation is finished. DES allows us to use 8 characters string as a key while AES allows 16 characters key and DESede allows 24 characters key. Let's try to encrypt and decrypt string in Java.
First we define our secret key string. Since we want to try AES, we have a 16 characters string as the secret key. We also created the message and convert it to an array of byte.
Next we created a SecretKey object by passing our secret key and the algorithm name of our preference. In this case we passed AES and its 16 bytes secret key.
Next we created a Cipher object by passing, what Javadoc refers as, a transformation. It is a string that describes the operations to be performed on the given input to produce some output. There are several transformation strings we can choose depending on the algorithm we use. Since in this case we use AES, we use AES/ECB/PKCS5Padding. We can use other transformation string of our preference.
Then we initialize the Cipher object by passing it the secret key object we created before and a flag to tell the Cipher that we want to do encryption as stated on ENCRYPT_MODE.
Now we can start encryption by calling doFinal() on the Cipher object as we did above. The encrypted text is show below:
After successfully encrypting the message now we will try to decrypt it. The code below shows how we do it by simply passing the secret key and a flag indicating that now we are interested in decrypting a text instead of encrypting it.
The decryption happens when we call doFinal() on Cipher object as we did when encrypting message.
The decryption result is shown below:
Instead of providing a string of secret key, Java provides us a secret key generator class named KeyGenerator. Our code below shows how we can take advantage of this class to generate a random secret key:
KeyGenerator takes algorithm name as a parameter to generate the secret key for us.
Saturday, April 26, 2014
Message Digest in Java
Message Digest is a function to verify a message integrity. A sender sends a message along with its message digest. The recipient then has to generate a new message digest from the original message. If the two message digests are equal then the message is verified. There are several algorithms we can use to generate message digest hash code including MD2, MD5, SHA-1, SHA-256, SHA-384, SHA-512. Let's now try to generate a message digest using MessageDigest class.
First we create the message and convert it to array of byte.
Then we create a MessageDigest object by passing an algorithm name of our preference. In the code above we passed "SHA-512". Next we update the object with our original message.
We then call digest() method of MessageDigest object against our original message to generate the message digest byte. Converting the byte to String using UTF8 encoding enables us to display the generated message digest to console as shown below.
This message digest is sent along with the original message. The recipient has to generate a new message digest against the original message as we did before. If the two message digests are equal then the original message is verified. Message digest is used to guarantee that the original message is intact because if the original message is changed even a bit, the MessageDigest will generate a completely different digest.
First we create the message and convert it to array of byte.
Then we create a MessageDigest object by passing an algorithm name of our preference. In the code above we passed "SHA-512". Next we update the object with our original message.
We then call digest() method of MessageDigest object against our original message to generate the message digest byte. Converting the byte to String using UTF8 encoding enables us to display the generated message digest to console as shown below.
This message digest is sent along with the original message. The recipient has to generate a new message digest against the original message as we did before. If the two message digests are equal then the original message is verified. Message digest is used to guarantee that the original message is intact because if the original message is changed even a bit, the MessageDigest will generate a completely different digest.
Sunday, December 29, 2013
WebSocket
Back in December 2012 when googling about websocket, the results were Atmosphere, jWebSocket, websockets4j, socket.io, and Weberknecht. But in December 2013, the result is JSR 356. Yes, there is finally a standardization about websocket. Apache Tomcat 7.0.47 has also implemented it and we will use it in this blog post.
To start, we can create usual dynamic web project in eclipse. Don't forget to specify Tomcat as the server target runtime. I created a super simple chat application. The chat room can have many users. You can try it by opening as many tabs as you like, each tab represents a new user session. All messages are saved so that users that joined after the conversation has started don't miss anything. In this example, each time a message is sent it will be broadcasted to all users joining the chat. Below is the source code hosted on box:
Below is the result when running the code with three users involved:
To start, we can create usual dynamic web project in eclipse. Don't forget to specify Tomcat as the server target runtime. I created a super simple chat application. The chat room can have many users. You can try it by opening as many tabs as you like, each tab represents a new user session. All messages are saved so that users that joined after the conversation has started don't miss anything. In this example, each time a message is sent it will be broadcasted to all users joining the chat. Below is the source code hosted on box:
Below is the result when running the code with three users involved:
Thursday, December 26, 2013
Monday, August 26, 2013
My Story on Java Memory Leak
Weeks ago I got an email saying that someone investigated our application (well, the application is neither initially designed nor implemented by me to be precise). Apparently he was hired by our client to find problems and give advice on how to increase application's performances. One of his findings that was sent to me to analyse was a memory leak report. I didn't have an idea on how Java can create memory leak. I understand that we have to destroy an object and release its memory, only if we, our self, allocate memory as in C. Turned out, there are many ways to create memory leak in Java through inappropriate use of design and code. These are the reports that were sent to me.
Having little knowledge of this application's design now I need to find the root cause of this? Great. The report shows that the top three memory consumers are Hibernate SessionFactoryImpl so it must be something to do with Hibernate. My first step was I need to be able to reproduce the report, see if it happens on my local machine (hoping that it only happens on production machine so I can blame the production environment :p). The report was generated using Eclipse Memory Analyser Tool (MAT), so I run it and boom the MAT produced completely same report. Interestingly, the memory leak happens even after the application was deployed on Weblogic App Server.
First, I thought the session was not properly closed. But looking at the code, it uses getCurrentSession() method provided by Hibernate and then by reading at Hibernate document I knew that it is maintained by Hibernate, developers are not allowed to close it manually.
So then how about Hibernate configuration? I changed the configuration a bit here and there.
<prop key="hibernate.connection.release_mode">after_statement</prop>
The connection must be released immediately after a statement is run.
<prop key="hibernate.cache.use_query_cache">false</prop>
I disabled the query cache.
<prop key="hibernate.transaction.flush_before_completion">true</prop>
Each transaction is flushed immediately.
<prop key="hibernate.transaction.auto_close_session">true</prop>
Each session is closed automatically.
But none of them cure the problem. Until then I realized that the SessionFactoryImpl was loaded because Hibernate check named query at startup. So I set this startup_check to false.
<prop key="hibernate.query.startup_check">false</prop>
Then the report shows the actual culprit. The root cause is our ApplicationContextLoader.
The configuration is loaded statically when the class is loaded by using static block. Moreover, it is set to a static variable which means it stays forever until the ApplicationContextLoader class is unloaded from memory.
Having little knowledge of this application's design now I need to find the root cause of this? Great. The report shows that the top three memory consumers are Hibernate SessionFactoryImpl so it must be something to do with Hibernate. My first step was I need to be able to reproduce the report, see if it happens on my local machine (hoping that it only happens on production machine so I can blame the production environment :p). The report was generated using Eclipse Memory Analyser Tool (MAT), so I run it and boom the MAT produced completely same report. Interestingly, the memory leak happens even after the application was deployed on Weblogic App Server.
First, I thought the session was not properly closed. But looking at the code, it uses getCurrentSession() method provided by Hibernate and then by reading at Hibernate document I knew that it is maintained by Hibernate, developers are not allowed to close it manually.
So then how about Hibernate configuration? I changed the configuration a bit here and there.
<prop key="hibernate.connection.release_mode">after_statement</prop>
The connection must be released immediately after a statement is run.
<prop key="hibernate.cache.use_query_cache">false</prop>
I disabled the query cache.
<prop key="hibernate.transaction.flush_before_completion">true</prop>
Each transaction is flushed immediately.
<prop key="hibernate.transaction.auto_close_session">true</prop>
Each session is closed automatically.
But none of them cure the problem. Until then I realized that the SessionFactoryImpl was loaded because Hibernate check named query at startup. So I set this startup_check to false.
<prop key="hibernate.query.startup_check">false</prop>
Then the report shows the actual culprit. The root cause is our ApplicationContextLoader.
The configuration is loaded statically when the class is loaded by using static block. Moreover, it is set to a static variable which means it stays forever until the ApplicationContextLoader class is unloaded from memory.
Wednesday, May 1, 2013
Java Web Start
Creating simple Java Web Start application is quite simple. There are three things we need to do.
1. Create the main class and wrap it in a JAR file. For simplicity sake, the main class extends JFrame that contains a JButton inside a JPanel as shown below:
2. Create a JNLP (Java Network Launch Protocol) file that links to the JAR file.
This file is an xml file and the structure is quite self explanatory. The main things here are the codebase attribute in <jnlp> element and the <jar> tag inside <resources> element. The codebase describes base path for all href in the file, in this case it is the base path to find jnlp.jnlp and jnlp.jar since I put those two files in the same folder. The jnlp.jar contains a main class which is stated in main="true" and main-class="edu.mat.jnlp.Main".
3. Create a HTML file that contains a link to the JNLP file.
Opening the HTML in a browser displays the following screen
Clicking the launch button launches the application as shown below:
1. Create the main class and wrap it in a JAR file. For simplicity sake, the main class extends JFrame that contains a JButton inside a JPanel as shown below:
2. Create a JNLP (Java Network Launch Protocol) file that links to the JAR file.
This file is an xml file and the structure is quite self explanatory. The main things here are the codebase attribute in <jnlp> element and the <jar> tag inside <resources> element. The codebase describes base path for all href in the file, in this case it is the base path to find jnlp.jnlp and jnlp.jar since I put those two files in the same folder. The jnlp.jar contains a main class which is stated in main="true" and main-class="edu.mat.jnlp.Main".
3. Create a HTML file that contains a link to the JNLP file.
Opening the HTML in a browser displays the following screen
Clicking the launch button launches the application as shown below:
Sunday, February 17, 2013
Simple Drools Example
Implementing an expert system using Drools is quiet easy. First of all create ordinary java project in Eclipse. The following image shows the project structure in Eclipse:
There are two source folders, first one is src/main/java to save java classes and second one is src/main/rules to save Drools rule files. Don't forget to include all required libraries in Drools distribution archive to this project. Two important files that need attention are Main.java and validation.drl. Let's see each of them.
The Main.java contains one method main(). In the main method we load the validation.drl file, create a Customer object, and then fire the validation rule. We also add a Map object that is used to save error messages during validation process. Next we will see the validation.drl.
The .drl file has its own format structure. First we state package name, this is used for grouping only. No same Drools file name exists in the same package. Then we import all classes just like we do in java file. Next we create a series of rules.
In the validation.drl above we have two rules, addressMandatory to validate address, and emailMandatory to validate email. In the when clause we get objects that are inserted through session in KnowledgeBase before; the HashMap object which we put inside a variable named errors for later use and also Customer object that we put inside a variable named cust. While addressMandatory rule checks whether the customer's address is null or not, emailMandatory rule checks whether the customer's email is either null or empty.
If the address or email is null we put an error message to the errors variable so that we can write it to console in the main() method. We can safely write any Java code inside the then clause as we do in ordinary java file.
When we run the main() method, the following output is displayed on console:
There are two source folders, first one is src/main/java to save java classes and second one is src/main/rules to save Drools rule files. Don't forget to include all required libraries in Drools distribution archive to this project. Two important files that need attention are Main.java and validation.drl. Let's see each of them.
The Main.java contains one method main(). In the main method we load the validation.drl file, create a Customer object, and then fire the validation rule. We also add a Map object that is used to save error messages during validation process. Next we will see the validation.drl.
In the validation.drl above we have two rules, addressMandatory to validate address, and emailMandatory to validate email. In the when clause we get objects that are inserted through session in KnowledgeBase before; the HashMap object which we put inside a variable named errors for later use and also Customer object that we put inside a variable named cust. While addressMandatory rule checks whether the customer's address is null or not, emailMandatory rule checks whether the customer's email is either null or empty.
If the address or email is null we put an error message to the errors variable so that we can write it to console in the main() method. We can safely write any Java code inside the then clause as we do in ordinary java file.
When we run the main() method, the following output is displayed on console:
Saturday, February 16, 2013
Java Compiler API
Java Compiler API has been around for a while since Java 6. We can use it to compile java files at runtime. Let's now have fun with it:
Inside main method above we have two java files to compile. Next we obtain the JavaCompiler object from ToolProvider. The JavaCompiler object then does its job to compile those files using verbose parameter supplied. Verbose parameter is useful to display compilation log. When we run the code, two .class files are created at the same location of the original files. Here is the output on console:
Let's now see another approach to compile java files.
First we state the files to compile. Then we obtain the JavaCompiler object from ToolProvider as we did before. After that we create an object of type DiagnosticCollector. This object is used to collect information during compilation process. Next, we get a StandardJavaFileManager by passing the DiagnosticCollector to the JavaCompiler's method getStandardFileManager. From the StandardJavaFileManager we create an Iterable object that contains the files being compiled. Then the actual compilation process is done by CompilationTask object by calling call() method. If an error occurs during compilation, we print the error information that has been collected by our DiagnosticCollector.
Instead of using DiagnosticCollector, we can use DiagnosticListener to collect error information. To do that we have to implement DiagnosticListener interface as shown below:
Then we can use it to compile java files as shown below:
We should be familiar with the code above since in fact we have seen it before. The only difference is that we replace the DiagnosticCollector with our own MyDiagnosticListener. Both DiagnosticCollector and MyDiagnosticListener implements DiagnosticListener interface.
So far we have seen how to compile java files reside on disk. Next we'll see how to compile java file from a string.
Again, the code above looks familiar but instead of getting the java content from files we get the java content from a string. The string itself is wrapped inside an object of type JavaObjectFromString which extends SimpleJavaFileObject which implements JavaFileObject as expected by our Iterable object.
To load the compiled class, we can use URLClassLoader by supplying it with a path where the compiled classes are put. Those classes are most likely compiled in the working directory.
Inside main method above we have two java files to compile. Next we obtain the JavaCompiler object from ToolProvider. The JavaCompiler object then does its job to compile those files using verbose parameter supplied. Verbose parameter is useful to display compilation log. When we run the code, two .class files are created at the same location of the original files. Here is the output on console:
Let's now see another approach to compile java files.
First we state the files to compile. Then we obtain the JavaCompiler object from ToolProvider as we did before. After that we create an object of type DiagnosticCollector. This object is used to collect information during compilation process. Next, we get a StandardJavaFileManager by passing the DiagnosticCollector to the JavaCompiler's method getStandardFileManager. From the StandardJavaFileManager we create an Iterable object that contains the files being compiled. Then the actual compilation process is done by CompilationTask object by calling call() method. If an error occurs during compilation, we print the error information that has been collected by our DiagnosticCollector.
Instead of using DiagnosticCollector, we can use DiagnosticListener to collect error information. To do that we have to implement DiagnosticListener interface as shown below:
Then we can use it to compile java files as shown below:
We should be familiar with the code above since in fact we have seen it before. The only difference is that we replace the DiagnosticCollector with our own MyDiagnosticListener. Both DiagnosticCollector and MyDiagnosticListener implements DiagnosticListener interface.
So far we have seen how to compile java files reside on disk. Next we'll see how to compile java file from a string.
Again, the code above looks familiar but instead of getting the java content from files we get the java content from a string. The string itself is wrapped inside an object of type JavaObjectFromString which extends SimpleJavaFileObject which implements JavaFileObject as expected by our Iterable object.
To load the compiled class, we can use URLClassLoader by supplying it with a path where the compiled classes are put. Those classes are most likely compiled in the working directory.
Subscribe to:
Posts (Atom)