Java Security: An application

Here, we shall develop a very simple but elegant application to demonstrate how to make use of all the concepts such as security manager, policy, jar signing and verifying etc. In this application, tom writes a Java program and Jerry wants to have it and run it. Let us now understand the steps they should follow for this purpose.

Suppose, tom has written the following program.

//FileSize.java import java.io.*; public class FileSize {

public static void main(String[] args) throws Exception {

InputStream in = new FileInputStream(args[0]);

int count = 0;

while (in.read() != -1) count++;

System.out.println(”Size of ”+args[0]+” = ”+count+” bytes”);

}

}

This application simply prints the size (in bytes) of a file specified as an argument. It is a useful application that anyone else can use, if required, to know the file size. Suppose, Jerry is one such person who wants to get it and run it. So tom generates a class file FileSize.ciass by compiling this program using the following command:

javac FileSize.java

Tom then creates a JAR file FiieSize.jar containing the FileSize.ciass file using command:

jar cvf FiieSize.jar FileSize.ciass

A sample result of this command is shown below:

added manifest

adding: FileSize.class(in = 867) (out= 530)(deflated 38%)

To sign this JAR file, tom creates a keystore containing private/public key pair as follows:

keytool -genkey -alias tom -keyalg RSA -keystore tom.jks -storepass 123456 –

keypass 123456 -dname ”CN=Tom, OU=IT, O=JU, L=Kolkata, ST=WB, C = IN”

Now you are ready to sign the JAR file. Type the following in your command window This private key in the keystore entry aliased by tom is used to sign the JAR file FiieSize.jar, to produce result JAR file tom.jar using the following command:

jarsigner -keystore tom.jks -storepass 123456 -signedjar tom.jar FiieSize.jar tom

Tom also exports its certificate in a file tom.cer that contains the public key corresponding to the private (that was used to sign the JAR file), which will be required by Jerry to authenticate tom.

keytool -export -keystore tom.jks -alias tom -storepass 123456 -file tom.cer

Jerry can now download the JAR file tom.jar containing the class file FileSize.ciass and use it. However, how can Jerry be sure that the JAR file tom.jar has not been tampered or trojaned by an intruder during its transit? Well, this can verified using jarsigner tool as follows:

jarsigner -verify tom.jar

If everything goes fine, the following message appears:

jar verified.

If verification fails, an appropriate diagnostic error message is displayed. In that case, Jerry continues to download it again until an unmodified version is obtained. Upon receiving a correct version, Jerry is ready to run the application. Note that the application FileSize.ciass gets the size of a file by reading the content of the entire file. Since it reads a file, it can see sensitive information (if any) present in that file. So, this application is a potentially vulnerable application and should be run within a security sandbox.

Suppose, Jerry wants to know the size of a file test.txt situated in the directory other than current directory. For example, suppose test.txt is placed in a sibling (having common parent) directory data. Jerry can use the following command:

java -Djava.security.manager -cp tom.jar FileSize ..\data\test.txt

This throws as exception:

Exception in thread “main” java.security.AccessControlException: access denied (

“java.io.FilePermission” “..\data\test.txt” “read”)

at

java.security.AccessControlContext.checkPermission(AccessControlConte xt.java:366)

at

java.security.AccessController.checkPermission(AccessController.java:555)

at

java.lang.SecurityManager.checkPermission(SecurityManager.java:549)

at java.lang.SecurityManager.checkRead(SecurityManager.java:888)

at java.io.FileInputStream.<init>(FileInputStream.java:131)

at java.io.FileInputStream.<init>(FileInputStream.java:97)

at FileSize.main(FileSize.java:5)

This is because the security manager consults only system and user policy files where no permission to read the file test.txt is specified. To allow accessing this file, permission must be given explicitly. This can be specified either in the existing policy files or in a separate policy file and specifying it either in java.security file or at runtime. To demonstrate how to work with a policy file, we shall give the permission in a separate policy file. Since, the code is a signed code, Jerry doesn’t grant permissions to any file named tom.jar but only to tom.jar archives that tom signed. To do that, Jerry needs to import Tom’s certificate in its trust store. So, copy the certificate tom.cer in Jerry’s working directory and use the following command:

keytool -import -v -keystore jerry.jks -storepass 123456 -alias tom -file tom.cer

When you test, make sure that the trust store Jerry does not already contain an entry aliased tom. Now, create the following policy file:

//jerry.policy

keystore “jerry.jks”, “jks”;

grant signedBy “tom” {

permission java.io.FilePermission “../data/*”, “read”;

};

This tells that any code signed by tom has the read access to all files under the sibling directory data of the present working directory. The signature can be verified against the public key which can be found in the certificate in the trust store jerry.jks corresponding to the entry tom. The verification of the JAR file against Jerry’s trust store may also be done explicitly as:

jarsigner -verbose -verify -keystore jerry.jks tom.jar

If verification is successful, it generates a message as follows:

This policy file can be specified in the command line as follows:

java -Djava.security.manager -Djava.security.policy=j erry.policy -cp tom.jar

FileSize ..\data\test.txt

The application reports the number of characters in the specified file without any error. Alternatively, the location of this policy file may be specified as the value of policy.url.n in the java.security file. For example, if jerry.policy is stored in a directory E:\ajp\sec\sm\jerry, then add the following line after the line starting with policy.url.2:

policy.url.3=file:/E:/ajp/sec/sm/jerry/jerry.policy

Source: Uttam Kumar Roy (2015), Advanced Java programming, Oxford University Press.

Leave a Reply

Your email address will not be published. Required fields are marked *