Showing posts with label Java SDK. Show all posts
Showing posts with label Java SDK. Show all posts

Wednesday, May 08, 2013

Java synchronized methods: lock on object or class

http://stackoverflow.com/questions/437620/java-synchronized-methods-lock-on-object-or-class

In section 8.1.1 of the Java Language
Specification, third edition. The valid modifiers for a class are any
annotation, public, protected, private, abstract, static, final, or
strictfp. It is illegal to place the keyword "synchronized" in front of
a class.

The Java Tutorials say: "it is not possible for two invocations of synchronized methods on the same object to interleave." What does this mean for a static method? Since a static method has no associated object, will the synchronized keyword lock on the class, instead of the object?
Yes.

Synchronized method acquires a monitor (§17.1) before it executes. For a class (static) method, the monitor associated with the Class object for the method's class is used. For an instance method, the monitor associated with this (the object for which the method was invoked) is used.

One point you have to be careful about (several programmers generally fall in that trap) is that there is no link between synchronized static methods and sync'ed non static methods, ie:
class A {
static synchronized f() {...}
synchronized g() {...}
}

Main:

A a = new A();
Thread 1:

A.f();
Thread 2:

a.g();
f() and g() are not synchronized with each other and thus can execute totally concurrently.

Unless you implement g() as follows:
g() {
synchronized(getClass()) {
...
}
}
I find this pattern useful also when I want to implement mutual exclusion between different instances of the object (which is needed when accesing an external resource, for example).

Monday, January 10, 2011

Just clarify the pass by value of Java

Remember long time ago, I ever saw a post talking about the refrence of Java. But with the passing of time, almost forget it compeltely. Recently, I looked at another post on the server side agruing the pass by reference. I have to reread it and make it much deeper in my mind. The follow artcile is a good one for pass by reference - http://javadude.com/articles/passbyvalue.htm.

Primitives are passed by value
Objects are passed reference by value (call by sharing)

Friday, October 22, 2010

How to use Unix shell script to send e-mail.

Recently, got problem to send e-mail from Unix with an existing shell script. It took me a long time to fixed. Here is the implementation of mine.

1. Mail sender



import java.io.BufferedReader;
import java.io.InputStreamReader;

public class MailSender {

public void send() throws Exception {
String[] cmd = { "sh", "/opt/app/test/SendEmail.sh",
"Victor Mail Sender", "hello Victor!", "mail@victor.net",
"victor@gmail.com" };

Runtime rt = Runtime.getRuntime();

Process p = rt.exec(cmd);

BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String x = null;
while ((x = br.readLine()) != null) {
System.out.println(x);
}
p.waitFor();
} finally {
try {
if (br != null)
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

public static void main(String[] args) {
try {
MailSender ms = new MailSender();
ms.send();
} catch (Exception e) {
e.printStackTrace();
}
}
}


In the above code, when we build the command used to send mail, we use "sh" as the first value of string array. If without this value, the SendEmail.sh must be set an executable permission. Using array to execute the shell script is to allow space in the subject and message body. If you put them in a string as a command to execute, it will not work and all the space in the command will be used as a separator.

The follow info is copied from The Java Developers Almanac.


     try {
       // Execute a command without arguments
       String command = "ls";
       Process child = Runtime.getRuntime().exec(command);
 
       // Execute a command with an argument
       command = "ls /tmp";
       child = Runtime.getRuntime().exec(command);
   } catch (IOException e) {
   }

   //If an argument contain spaces, it is necessary to use the overload that requires the command and its arguments to be supplied in an array:
   try {
       // Execute a command with an argument that contains a space
       String[] commands = new String[]{"grep", "hello world", "/tmp/f.txt"};
       commands = new String[]{"grep", "hello world", "c:\\Documents and Settings\\f.txt"};
       Process child = Runtime.getRuntime().exec(commands);
   } catch (IOException e) {
   }


Unix Shell Scirpt:


#!/usr/bin/ksh

# --------------------------
# 1, Set up environment
# --------------------------

LOG_HIS="./Mail.History.log"

#Current environment variable
TS=$(date +%Y%m%d-%H%M%S)

# ------------------------------------------------------------
# 2, Check parameter and write initial info into log
# ------------------------------------------------------------
echo "--------------------------- ${TS} -------------------------- "  >>${LOG_HIS}

# Check if has parameter
if [ "$#" -lt 4 ]
then
    echo "Error: Missed parameters !" >> ${LOG_HIS}
    exit 1
else
    from=$3
    to=$4
    Subject=$1
    body=$2
    
    echo "Subject:  ${Subject}" >> ${_LOG_HIS}
    echo "body:  ${body}" >> ${LOG_HIS}
    echo "From:  ${from}" >> ${LOG_HIS}
    echo "To:  ${to}" >> ${LOG_HIS}
fi

echo  $body |mailx -m -r $from -s "$Subject"  $to >> ${LOG_HIS}

exit 0

Monday, May 17, 2010

Java Security Packages JCA/JCE

In this tutorial, the author explains the cryptography-related concepts and packages in JDK, with code examples. Many of the concepts and technical terms thus learnt will be useful in understanding the Cryptography API in MFC also.

There are three security-related packages in JDK1.4, as follows:

1.  JCA/JCE (Java Cryptography Architecture & Java Cryptography Extensions)

2.  JSSE( Java Secure-Sockets Extension).

3.  JAAS( Java Authentication & Auhorization Service)

( Prior to JDK1.4, many of these packages were not available within the JDK and had to be separately installed and used. But, JDK1.4 has incorporated all these within JDK itself).

Understanding the terminology of these important packages requires that we have some familiarity with the technical terms used in the field of Network Security. We can begin by saying that secure communication ,should ensure the following.
  •  Integrity
  •  Confidentiality
  •  Authentication
  •  Non-repudiation
[ There is also another requirement (ie). Authorization and it is more to protect resources and programs from users, than with communicating the data. JAAS deals with that].

These are all standard terms used in Security. When a person, say, Sam, wants to send some information to Tom, it must be ensured that the information thus sent, is not tampered with or altered on the way. This is known as Data Integrity.

Secondly, the information is meant only for Tom and so no one else should be able to understand the message. This is known as Confidentiality. There should be some indication that the message came from Sam and there should be some proof for that. This is Identification. Authentication, that the message came from Sam is provided by Digital Signature. There should preferably be a trusted third party to vouchsafe for the identity and signature of Sam. This is achieved by Digital Certificate, which authenticates the signature of Sam. Besides these, sometimes it is equally important that Sam should not be able to say later that he did not send the message to Tom and the message was actually sent by someone else ,in his name. This is ensuring Non-repudiation. This purpose also is served by Digital signature. We will now see step-by-step development of these concepts. Except 'Authorization', other things can be understood in the context of everyday exchange of information.

Confidentiality is achieved by using Cryptography techniques. For the sake of simple illustration, let us assume that Sam wants to send a message to Tom.( By convention, two persons Alice & Bob are chosen for illustration, because the original thesis made use of these names. Let us use Sam and Tom instead). Sam does not want his message to be understood by anybody else except Tom. So, he encrypts it. When Tom receives the encrypted message, he 'decrypts' it, so that he can read the original message. The original message is known as 'plaintext'. After Encryption, it becomes 'cipher text'. The process of converting the cipher text into the original plaintext is known as Decryption. A 'key' is used for controlling Encryption and Decryption.

There are two types of key-based encryption algorithms, namely, Symmetric algorithm and Asymmetric Algorithm.


I ).  Symmetric Algorithm: This algorithm uses the same key for encryption and decryption. This is also known as 'Secret key'.

In this scheme, when Sam wants to send a message to Tom, he encrypts the message by the mutually agreed secret-key and then sends the cipher text to Tom. Tom uses the same secret key and decrypts the message and reads it.

Symmetric key system is faster than the Asymmetric system but the problem of agreeing on mutual secret key and preserving the secrecy of the key while communicating it over the network, led to the development of Asymmetric key systems.

Some of the Symmetric key Algorithms are as follows: (Most of them are implemented in JCA/JCE).

1.  DES( Data-Encryption-Standard).. developed in 1970 and recommended by US government. Though it is not fool-proof, it is considered to be sufficiently safe and is in wide use.

It has different modes of operation.
  • Electronic Cook book ( ECB)
  • Cipher Block Chaining ( CBC)
  • Output Feedback Mode (OFB)
  • Cipher Feedback Mode ( CFB)
2. ) Triple DES( also known as DESede) ..

An improved and very safe method of DES.

3. ) IDEA (International Data Encryption Algorithm). This is used in PGP ( Pretty-Good-Privacy method of secure Email).

An important advantage of Secret-key algorithm is that a hardware-approach is possible. This results in very high speed encryption. The hardware implementation by a VLSI chip can be about 20 times faster than the corresponding software implementation! IDEA has been implemented in hardware.

4. ) Blowfish...This algorithm was designed by Bruce Schneier. It is not patented and he has placed the implementation in public domain.

5. ) There is also a method known as Password-Based Encryption (PBE). We will have a brief description of this method ,with code example, shortly.

Ready-made implementations for many of these algorithms are available in SunJCA/JCE and the programmer just chooses the desired algorithm and uses it. No deep knowledge of the mathematical theory of the algorithms or how these algorithms are implemented ,is required .Such topics are highly mathematical and are dealt with in books on Cryptography .

II ). Asymmetric Algorithms

This algorithm is also known as 'Public Key' algorithm. There are two keys in this scheme. One key is known as 'public key' and the other key is known as 'private key'.( It should be noted that 'secret key' does not mean 'private key'.)

The basic theory of Public key Cryptography was developed by two research workers at Stanford University Diffie & Hellman in 1976. The DH algorithm is known as Key-Agreement method. RSA algorithm is an implementation , named after the initials of the three academics who invented it. ( Rivest, Shamir & Adleman). RSA is the defacto standard. Another Asymmetric algorithm is DSA ( Digital Signature Algorithm). Yet another algorithm is known as ECC (Elliptic-Curve Cryptography). It is reputed to be very efficient and fast.
[ However, SunJCA/JCE does not provide ready-made implementation for ECC.]

The public key and private key are known as 'keypair'. The public key and private key are mathematically related in the sense that if a message is encrypted by using a particular public key, it can be decrypted by the corresponding private key and vice-versa (ie) the data can also be encrypted by using a private key and can be decrypted by the corresponding public key, and not by any other public key. But the problem is that any person who knows Sam's public key can decrypt the message. So, RSA system uses public key of the recipient to encrypt the data.( But, the private key cannot be derived from public key. Similarly, the public key cannot be derived from private key).

RSA method is the most widely used scheme. When Sam wants to send a secret message to Tom, he should know the public key of Tom to begin with.( Just as we should know the mail-id of our friend first, if we want to send email to him). Sam encrypts the message by using Tom's public key and sends it to Tom. At the receiving end, Tom uses his (Tom's) private key and decrypts the letter and reads it. The advantage of this scheme is that it ensures that only Tom will be able to read the message, as only his private-key can decrypt the message encrypted with his public key. A person's private key need never be known to anyone else and there is no sharing the key with another person. Only the public key needs to be informed to others. ( like the difference in sharing our mail-id and sharing our password!). Thus key-administration problem is less.

Digital Signature & Message Digest

The Asymmetric system has another use as well. It can be used for creating the Digital Signature, to ensure that the message came from Sam. Though the message itself can be signed without creating a digest, the usual method is to sign the message digest, so that Integrity of data also can be ensured.

A 'Message Digest' is a digital fingerprint. It is often referred to simply as a digest ( summary) or hash. It is an one-way process ( ie) it is impossible to reconstruct the original from the hash.

MD5(MessageDigest-5) and SHA-1( Secure Hash Algorithm) are two examples of such Digesting algorithms. These two are provided in Sun security package.MD5 accepts some input and produces a 128-bit message digest. SHA-1 is more secure and produces a 160-bit message digest.

When Sam wants to send a secure message, he passes the message through a Message Digest engine. The result is a hash.

He then encrypts the hash by using Sam's private key.( This encryption is done on the hash and not on the data). Thus we get the Digital Signature.

Finally, Sam encrypts the original message using Tom's Public key. After this, Sam sends the package to Tom.

At the receiving end, Tom uses his (Tom's) private key to decrypt the message. By using Sam's public key, he decrypts the digital signature and so gets the original hash( hash1). Using the same one way hash algorithm on the text message, Tom creates another hash( hash2).If hash2 exactly matches hash1, it means that the data has not been altered in transit. Thus, we get assurance of Confidentiality and Data Integrity. It also ensures the identity of the sender, becuase the the hash1 was obtained by using the public key of Sam to decrypt the package.

If the public key of Sam, used by Tom, has the added assurance from a certificate authority that it really belongs to Sam, this is a clear-cut method with no problems except that it is not suitable if the message being encrypted is of large size. Besides satisfying the requirements of Authentication, Confidentiality, Integrity and Non-Repudiation, we should also ensure that the process is fast, in Enterprise level. The method outlined above is slow and so may not be suitable for large messages. Otherwise, it is a satisfactory method.

(We will describe a hybrid method used for large messages, shortly).

Sometimes, it may be enough if there is Authentication and Non-Repudiation, without confidentiality. In such cases, it is enough if Sam sends the message-digest encrypted by Sam's privatekey ,along with the plaintext.

Digital Certificate
Just now , we saw that Tom made use of Sam's public key to verify his Digital Signature. How does Tom get to know the public key of Sam? Sam could have published his public key in the internet or could have sent it to Tom, personally. A person's public key can be freely published and shared and for this reason, anybody can use it , not necessarily Sam. A Digital signature of Sam can be verified only if Sam's public key is available to Tom but as it is a public key, impersonation is possible. A trusted third-party is required to certify that the said key is really Sam's public key. This is known as Digital Certificate and the authorities who issue such certifictes are Certifying Authority.

Public Key Infrastructure( PKI)
When Sam wants his public key to be certified by a CA, he generates a keypair and sends the public key to an appropriate CA with some proof of his identification.

The CA checks the identification and then after satisfying that the key has not been modified in transit, issues a certificate relating the public key of Sam with his identity, by signing the public key of Sam with the private key of the CA. The standard format of issuing the certificate is known as X509.

Who is to attest the CA themselves? The CA are self-attested.

The PKI standard has been developed by RSA Security Systems in collaboration with Industry leaders like SUN, IBM and Microsoft and is the industry standard.

Certificate-Revocation
A certificate becomes invalid after the expiry of validation period. Sometimes, the private key associated with a public key gets compromised ( ie) exposed, and in that case also, the certificate should be withdrawn( revoked). The owner of the private key also may like to change it. The CA publishes a list of such defunct certificates and Tom should verify that Sam's certificate is still valid, before important transactions.

Message-Authentication-Code ( MAC)

Digital Signature makes use of Sam's private key to sign the hash. An alternative to Digital Signature is to use a secret key to encrypt the hash. By its very definition, secret key is common to both Sam & Tom. So Tom can use the secret key at his end and get back the hash. The code thus generated by mixing the hash and the secret key is known as MAC. Digital Signature is better than MAC because it does not need any 'secret' key. In the context of E-Commerce, where there are thousands of parties , secret key administration is always very difficult.

The scheme outlined above is suitable for most purposes. However, for very large amounts of data, encryption and decryption of data by public-key systems becomes time consuming and requires large resources. In such cases, it is preferred to use Symmetric Encryption systems with some modifications. Hybrid Systems make use of Asymmetric method for agreeing upon a secret key and the actual encryption and decryption of data is done by this secret key. Some such method is the usual Industrial practice. The Secret key used here is valid only for a particular instance of transmission of message and so is usually called 'session-key'. ( This is not the 'session' as usually understood in servlates, because this is an one-time operation).

Digital Envelope

An illustration of Hybrid method is a Digital Envelope. In this scheme, Sam encrypts the message by a random Secret key, ( known as DEK i.e. Data-Encryption-key or session key). Next Sam encrypts this session key with Tom's public key. At this stage, Sam sends both the encrypted message and the encrypted session key to Tom.

At the receiving end, Tom uses his private key to get the session key. Using this session key, Tom decrypts the message. As Symmetric method is about 1000 times faster than Asymmetric method , this is a good combination. Though public key method also has been used here, it is only for encrypting the session key and not the message. This can be further improved by creating a hash of the message and signing it. Also, there is no permanent Secret key between Sam & Tom, and the required secret key is produced just as required and then discarded after the job. Thus, the method is fast and secure.

With this background information, let us now see some simple code examples, specific to JDK.

There are a number of Cryptographic Engines in Sun JCA & Sun JCE. They are listed below.

It will be immediately evident that the names will be Greek & Latin to us , unless we have a background in Crypto terminology. That is why, a broad outline was given. The function of some of the engines will be evident from the earlier discussion. A few more of the remaining items will be clear when we deal with code examples.

Cryptographic Engines
  •  Key Generator ( symmetric)
    (Blowfish, DES, Triple DES, HmacMD5, HmacSHA1,RC5)
  •  Key Pair Generator ( asymmetric)
    (Diffie Hellman, DSA, RSA)
  •  Mac ( message authentication code)
    ( HmacMD5, HmacSHA1)
  •  Message Digest
    (MD5, SHA1)
  • Signature
    ( MD5withRSA, SHA1withRSA, SHA1withDSA)
  • Cipher
    ( Blowfish, DES, Triple DES etc)
  • Certificate Factory
    ( X509)
  • Key Agreement
    ( Diffie Hellman)
  • Key Factory
  • Secret Key Factory
  • Secure Random
    ( SHA1PRNG) (ie)
    ( SHA1 ..pseudo-random-number-generator)
  • Trust Manager Factory
  • Key Manager Factory
  • Key Sore
    ( JKS, PHCS12)
  • SSL Context
  • Algorithm Parameter Generator
  • Algorithm Parameters
Let us now see a series of code-examples to get familiarity with some of the above engines. For all the examples, we are using JDK1.4.2. Our working directory is g:\securitydemos. CD to g:\securitydemos

We should set path as : c:\windows\command;d:\jdk1.4.2\bin

The easiest to understand is the Message Digest. "demo1.java" creates the message digest of the string s1, by SHA method (Secure Hash Algorithm) . The given string is first converted into a byte array, because the function md. digest(), accepts only a bytearray. md. update() simply adds the array to existing arrays, if any. The digest object thus created is simply saved as object to the file.

// demo1.java 
// creation of message-digest
// storing the string & digest in file
import java.io.*;
import java.security.*;

class demo1 {
   public static void main(String args[]) {
     try { 
       MessageDigest md = MessageDigest.getInstance("SHA"); 
       String s1 = " we are learning java";
       byte[] array = s1.getBytes();
       md.update(array);
       FileOutputStream fos = new FileOutputStream("demo1test");
       ObjectOutputStream oos = new ObjectOutputStream(fos);
       oos.writeObject(s1);
       oos.writeObject(md.digest ());
       System.out.println(" digest ready!");
     }catch(Exception e1) {
       System.out.println(""+e1);
     }
   }
}

In demo2.java, we learn how a given messagedigest can be used for checking up for Integrity of data. We begin by getting the original string as well as the existing hash. Next we create another hash of the original string by the same algorithm to get hash2. Then, we compare hash1 with hash2. If they are not equal, we get the message "corrupted". From these examples, it will be appreciated how much the Java API shields the programmer from the inner workings of the highly mathematical theory of Cryptology.

----------------------------------------

// demo2.java
// getting a string and digest from file
// creating a hash and verifying the digest
import java.io.*;
import java.security.*;
class demo2 {
  public static void main(String args[]){
    try {
       FileInputStream fis = new FileInputStream("demo1test");
       ObjectInputStream ois = new ObjectInputStream(fis);
       Object ob1 = ois.readObject();
       String s1 = (String) ob1;
 
       System.out.println(s1);

       Object ob2 = ois.readObject();
       byte[] array1= (byte[]) ob2;
       MessageDigest md = MessageDigestgetInstance("SHA");
       md.update(s1.getBytes());
       if(MessageDigest.isEqual(md.digest(), array1)) {
         System.out.println("valid"); 
       }else{          System.out.println("corrupted");
       }
    } catch(Exception e1){
       System.out.println(""+e1);
    }
  }
}

In the third example(demo3.java) , we see how a secret key is created by the DES algorithm. Cipher class is the Encryption and Decryption engine.After initialising the Cipher engine for encrypting mode, we

give the command ci.doFinal(). This creates the encrypted message of the specified string. We should also get the initvector, by the command ci.getIV().

To avoid writing a separate example, we illustrate the process of decrypting also here, in the next stage. We get the initvector and then define the cipher for decrypt mode. After this , ci.doFinal(), does the decryption.

// demo3.java
// creation of secret key
// encryption using secret key
// decryption using secret key

import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
class demo3 {
   public static void main(String args[]) {
     try {
       KeyGenerator kg = KeyGenerator.getInstance("DES");
       // DES= Data Encryption Standard
       Key key = kg.generateKey();
       Cipher ci = Cipher.getInstance("DES/CBC/PKCS5Padding");
       ci.init(Cipher.ENCRYPT_MODE, key);
       String s ="we are learning Java";
       byte[] array1 = s.getBytes();
       byte[] array2 = ci.doFinal(array1);
       byte[] initvector = ci.getIV();
       System.out.println ("string has been encrypted");
       System.out.println ("we are now decrypting");
       IvParameterSpec spec = new IvParameterSpec(initvector);
       ci.init (Cipher.DECRYPT_MODE, key, spec);
       byte[] array3 = ci.doFinal(array2);
       String s2 = new String(array3);
       System.out.println(s2);
    }catch(Exception e1){
       System.out.println(""+e1);
    }
  }
}


The following program displays information about the Providers available in JDK.

// demo4.java
import java.security.*;
import java.util.*;
class demo4 {
   public static void main(String args[]) {
     try {
       Provider[] array = Security.getProviders();
       int n = array.length;
       for(int j=0; j
         System.out.println(array[j]);
         for(Enumeration e=array[j].keys(); e.hasMoreElements();) {
           System.out.println("\t"+e.nextElement());
         }
       }
     } catch(Exception e1) {
       System.out.println(""+e1);
     }
  }
}

When we execute the program, we get a long list We can run the program as:

>java demo4 > list.txt

and then inspect list.txt

In demo5 , we create a privatekey/publickey pair, by using

the DSA( Digital Signature Algorithm).

The Key Pair Generator class is used for that, by specifying a pseudo-random number. The key pair is easily generated by the command, kpg.genKeyPair(). After this we get get the public key and private key. Next we specify the Signature algorithm as Secure Hash DSA. After initializing the sig with the private key, we create the byte array for the string to be signed and ask the sig to sign that array [sig. sign();]

Now the data string has been signed by the sender's private key. In the next section, we have loaded sig with the public key and used the command to verify with the original array.. This will return 'true' , if the keys belong to the same pair. The code is almost self-explanatory, except for the syntax.

When we run the program demo5 , we get the following output.

G:\SECURI~1>java demo5

public & private keys ready!

the data has been signed by private key

now verifying with public key

verified & found ok

// demo5.java
// creation of public & private keys
// signing the data by private key
// verifying the data by public key

import java.security.*;
import javax.crypto.*;
class demo5 {
   public static void main(String args[]) {
     try {
       SecureRandom sr = new SecureRandom();
       byte[] pr =new byte[100];
       sr.nextBytes(pr);
       KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
       kpg.initialize(512,sr);
       KeyPair kp = kpg.genKeyPair();
       PublicKey pubkey = kp.getPublic();
       PrivateKey prikey = kp.getPrivate();
       System.out.println ("public & private keys ready!");
       Signature sig = Signature.getInstance("SHA1withDSA");
       sig.initSign(prikey);
       String s1 = "we are learning Java";
       byte[] array1= s1.getBytes();
       update(array1);
       byte[] array2 = sig.sign();
       System.out.println ("the data signed by private key");
       System.out.println ("now verifying with public key");
       sig.initVerify(pubkey);
       sig.update(array1);
       boolean ok = sig.verify(array2);
       if(ok==true){
          System.out.println("authentic..ok");        } else{
          System.out.println("not authentic");
       }
   } catch(Exception e1){
       System.out.println(""+e1);
   }
}

We will conclude this tutorial with an illustration for Password-based secret key.

Users are supposed to remember their password, easily. If a secret key can be generated based on the password, it will be easier to generate. Users can then generate such a secret key and use it to encrypt and decrypt their files. The algorithm uses a 'salt' and an integer number for iteration. The paramspec is created using these two values. The Cipher engine for PBEWithMD5AndDES( PBE=Password-based-encryption, MD5=MessageDigest-5 &DES=Data Encryption Standard) is then created. The program asks for a password and then the string to be encrypted. A secret key based on the password supplied is generated and used to encrypt the data.

Just for illustration, the program asks for the password again. When we type it correctly, the secret key is again generated and used to decrypt the encrypted data. Finally, the original string is printed.

The output of demo6 is shown below.

( system prompt & output in bold)

G:\SECURI~1>java demo6

enter the password

abcd1234

enter the string to be encrypted

we are studying java cryptography

encryption over

now decrypting

enter the password again!

abcd1234

we are studying java cryptography

// demo6.java
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.io.*;

class demo6 {
   public static void main(String args[]) {
     String salt="saltings";
     int n = 20; // iterations
     byte[] a = salt.getBytes();
     PBEParameterSpec paramspec= new PBEParameterSpec (a,n);
     try {
       Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");
       DataInputStream ins = new DataInputStream(System.in);

       System.out.println ("enter the password");
       String s1=ins.readLine();
       System.out.println("enter the datastring");
       String s2=ins.readLine();
       byte[] array1 = s2.getBytes();
       PBEKeySpec keyspec = new PBEKeySpec(s1.toCharArray());
       SecretKeyFactory factory= SecretKeyFactory.getInstance ("PBEWithMD5AndDES");
       SecretKey key = factory.generateSecret(keyspec);
       cipher.init (Cipher.ENCRYPT_MODE, key, paramspec);
       byte[] array2 = cipher.doFinal(array1);
       System.out.println("encryption over");
       System.out.println("now decrypting");
       System.out.println ("enter the password again!");
       String s3=ins.readLine();
       keyspec = new PBEKeySpec(s3.toCharArray());
       factory= SecretKeyFactory.getInstance("PBEWithMD5AndDES");
       key = factory.generateSecret(keyspec);
       cipher.init (Cipher.DECRYPT_MODE, key, paramspec);
       byte[] array3 = cipher.doFinal(array2);
       String s4=new String(array3);
       System.out.println(s4);
     } catch(Exception e1){
       System.out.println(""+e1);
     }
   }
}

That completes our introductory tutorial

on JCA/JCE. All the above programs have been tested and are working correctly. Students are encouraged to follow this up with the reference material mentioned below:

RERFERENCE BOOKS
  • Mastering Java Security
    (Cryptography, Algorithms & Architecture) by Rich Helton & Johennie Helton ( Wiley/ DreamTech)
  • Professional Java JDK 5 edition. Clay Richardson & others ( chapter- ) Wrox/Wiley/DreamTech
  • Java Security by Scott Oaks ( of SUN MICRO SYSTEMS) ( SPD/OReilley)
  • Java Distributed Objects by Bill McCarty ( chapter- )
  • Professional Java Web Services by Mack Hendricks (SUN) & others chapter-6 on Security by James Millbury

Thursday, March 18, 2010

How to get the invocation hierarchy in Java?

In Java, we can see the invocation hierarchy sometimes in Java. Especially, the log4j can log the class into log file with package name, method and line even. How can we implement the similar functionality?

First, how can we get the invocation class and method? Stack trace.

StackTraceElment[] ste = new Throwable().getStackSTrace();

In the array of StackTraceElement, we can find the hierarchy of current stack. By this, we can get the invocation map of whole stack.

StackTraceElment APIs:
String getClassName()
Returns the fully qualified name of the class containing the execution point represented by this stack trace element.
String getFileName()
Returns the name of the source file containing the execution point represented by this stack trace element.
int getLineNumber()
Returns the line number of the source line containing the execution point represented by this stack trace element.
String getMethodName()
Returns the name of the method containing the execution point represented by this stack trace element.

In Java 5, The Thread introduced two new methods: getStackTrace() and getAllStackTraces(). Now we don't need to use (new Throwable()).getStackTrace() and by using Thread.getCurrentThread().getStackTrace() to get the stack trace info. Not only doing so, but also we can get stack trace of other threads if we have the enough permission.

Thursday, December 10, 2009

Why use Map.entrySet() instead of Map.keySet()?

(From http://www.coderanch.com/t/382487/Java-General/java/Why-use-Map-entrySet)

If you just need keys, use keySet(). If you just need values, use values(). If you're going to use keys and values in your subsequent code, then you're best off using entrySet().

I frequently see people do this without entrySet(), and it usually looks something like this:

for (Iterator it = map.keySet().iterator(); it.hasNext(); ) {
Foo key = (Foo) it.next();
Bar value = (Bar) map.get(key);
// now do something with key and value
}

This works, but it's making the JVM do extra work for no good reason. Every time you call get() you're making the JVM spend time doing a hashcode lookup, or navigating a tree and evaluating a comparator. These operations may be fast, or not, but why do them if you don't have to? A Map.Entry gives you both key and value, together, in the most efficient manner possible.

for (Iterator it = map.entrySet().iterator(); it.hasNext(); ) {
Map.Entry e = (Map.Entry) it.next();
Foo key = (Foo) e.getKey();
Bar value = (Bar) e.getValue();
// now do something with key and value
}


Under JDK 5 and later it's a little nicer:

for (Map.Entry e : map.entrySet()) {
Foo key = e.getKey();
Bar value = e.getValue();
// now do something with key and value
}

Monday, October 19, 2009

Learn to Use the New Annotation Feature of Java 5.0

A article for annotation of Java 5 from http://www.devx.com/Java/Article/27235/1954?pf=true

What Are Annotations?
In short, annotations are metadata or data about data. Annotations are said to annotate a Java element. An annotation indicates that the declared element should be processed in some special way by a compiler, development tool, deployment tool, or during runtime.

Annotations can be analyzed statically before and during compile time. Annotations will likely be used before compile time mainly to generate supporting classes or configuration files.For example, a code generator (XDoclet, for example) can use annotation data in an EJB implementation class to generate EJB interfaces and deployment descriptors for you, reducing both your effort and the error rate. The average developer will probably not be writing code-generation tools, so these annotation types are likely to be used out-of-the-box rather than authored anew.

Annotations will also be used for compile-time checking such as to produce warnings and errors for different failure scenarios. An example of an annotation that is used at compile time is the new @Deprecated annotation, which acts the same as the old @deprecated JavaDoc tag.

Annotations can be useful at runtime as well. Using annotations you could mark code to behave in a particular way whenever it is called.For example, you could mark some methods with a @prelog annotation.

Another way to use annotations at runtime is to use Aspect-Oriented Programming (AOP). AOP uses pointcuts—sets of points configured to executed aspects. You could define a pointcut that will execute an aspect for an annotated method. My guess is that developers would be more likely to write their own runtime annotation types than they would annotation types used for code generation and compile-time checking. Still, writing and understanding the code that accesses the annotations (the annotation consumer) at runtime is fairly advanced.

Annotating Code
Annotations fall into three categories: normal annotations, single member annotations, and marker annotations (see Table 1). Normal and single member annotations can take member values as arguments when you annotate your code.

1. Normal Annotations—Annotations that take multiple arguments. The syntax for these annotations provides the ability to pass in data for all the members defined in an annotation type.
Example: @MyNormalAnnotation(mem1="val1", mem2="val2") public void someMethod() { ... }

2. Single Member Annotations—An annotation that only takes a single argument has a more compact syntax. You don't need to provide the member name.
Example: @MySingleMemberAnnotation("a single value") public class SomeClass { ... }

3.Marker Annotations—These annotations take no parameters. They are used to mark a Java element to be processed in a particular way.
Example: @Deprecated public void doWork() { ... }

Any Java declaration can be marked with an annotation. That is, an annotation can be used on a: package, class, interface, field, method, parameter, constructor, enum (newly available in Java 1.5), or local variable. An annotation can even annotate another annotation. Such annotations are called meta-annotations.

Packages annotations are also allowed, but because packages are not explicitly declared in Java, package annotations must be declared in a source file called package-info.java in the directory containing the source files for the package.

Built-in Annotations
Java 1.5 comes packaged with seven pre-built annotations.
  • java.lang.Override,
  • java.lang.Deprecated,
  • java.lang.SuppressWarning,
    (The follows are meta-annotation.)
  • java.lang.annotation.Documented,
  • java.lang.annotation.Inherited,
  • java.lang.annotation.Retention,
  • java.lang.annotation.Target

    Declaring Annotation Types
    Now that you've learned a little about the annotations that come packaged with Java 1.5, you can move on to declaring your own annotation types.

    Here is a sample annotation type:


    public @interface MyAnnotationType {
    int someValue();
    String someOtherValue();
    String yesSomeOtherValue() default "[blank]";

    }



    The annotation consumers are the development tools, the compiler, or a runtime library that accesses the annotation data you created when you annotated your Java code.

    An example of how you can access your code during runtime using the reflection API.


    // The Annotation Type
    import java.lang.annotation.Retention;
    import static java.lang.annotation.RetentionPolicy.RUNTIME;

    @Retention(RUNTIME)
    public @interface GreetsTheWorld {
    public String value();
    }

    // The Annotated Class
    @GreetsTheWorld("Hello, class!")
    public class HelloWorld {

    @GreetsTheWorld("Hello, field!")
    public String greetingState;

    @GreetsTheWorld("Hello, constructor!")
    public HelloWorld() {
    }

    @GreetsTheWorld("Hello, method!")
    public void sayHi() {
    }
    }

    // The Annotation Consumer
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;

    public class HelloWorldAnnotationTest
    {
    public static void main( String[] args ) throws Exception
    {
    //access the class annotation
    Class clazz = HelloWorld.class;
    System.out.println( clazz.getAnnotation( GreetsTheWorld.class ) );

    //access the constructor annotation
    Constructor constructor =
    clazz.getConstructor((Class[]) null);
    System.out.println(
    constructor.getAnnotation(GreetsTheWorld.class));

    //access the method annotation
    Method method = clazz.getMethod( "sayHi" );
    System.out.println(method.getAnnotation(GreetsTheWorld.class));

    //access the field annotation
    Field field = clazz.getField("greetingState");
    System.out.println(field.getAnnotation(GreetsTheWorld.class));
    }
    }

  •