Java security jar file

Signing and verifying a standalone JAR

Last week, I wrote about the JVM policy file that explicitly lists allowed sensitive API calls when running the JVM in sandboxed mode. This week, I’d like to improve the security by signing the JAR.

This is the 3 rd post in the JVM Security focus series.Other posts include:

The nominal way

This way doesn’t work. Readers more interested in the solution than the process should skip it.

Create a keystore

The initial step is to create a keystore if none is already available. There are plenty of online tutorials showing how to do that.

keytool -genkey -keyalg RSA -alias selfsigned -keystore /path/to/keystore.jks -storepass password -validity 360

Fill in information accordingly.

Sign the application JAR

Signing the application JAR must be part of the build process. With Maven, the JAR signer plugin is dedicated to that. Its usage is quite straightforward:

  maven-jarsigner-plugin 1.4   sign  sign     /path/to/keystore.jks selfsigned $ $ 

To create the JAR, invoke the usual command-line and pass both passwords as system properties:

mvn package -Dstore.password=password -Dkey.password=password

Alternatively, Maven’s encryption capabilities can be used to store passwords in a dedicated settings-security.xml to further improve security.

Configure the policy file

Once the JAR is signed, the policy file can be updated to make use of it. This requires only the following configuration steps:

keystore "keystore.jks"; grant signedBy "selfsigned" codeBase "file:target/spring-petclinic-1.4.2.jar"

Notice the signedBy keyword followed by the alias name — the same one as in the keystore above.

Launching the JAR with the policy file

The same launch command can be used without any change:

java -Djava.security.manager -Djava.security.policy=jvm.policy -jar target/spring-petclinic-1.4.2.jar

Unfortunately, it doesn’t work though this particular permission had already been configured!

Caused by: java.security.AccessControlException: access denied ("java.lang.reflect.ReflectPermission" "suppressAccessChecks") at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472) at java.security.AccessController.checkPermission(AccessController.java:884) at java.lang.SecurityManager.checkPermission(SecurityManager.java:549) at java.lang.reflect.AccessibleObject.setAccessible(AccessibleObject.java:128) at org.springframework.util.ReflectionUtils.makeAccessible(ReflectionUtils.java:475) at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:141) at org.springframework.boot.SpringApplication.createSpringFactoriesInstances(SpringApplication.java:420)

The strangest part is that permissions requested before this one work all right. The reason is to be found in the particular structure of the JAR created by the Spring Boot plugin: JAR dependencies are packaged untouched in a BOOT-INF/lib folder in the executable JAR. Then Spring Boot code uses custom class-loading magic to load required classes from there.

JAR signing works by creating a specific hash for each class, and by writing them into the JAR manifest file. During the verification phase, the hash of a class is computed and compared to the hash of the manifest. Hence, permissions related to classes located in the BOOT-INF/classes folder work as expected.

However, the org.springframework.boot.SpringApplication class mentioned in the stack trace above is part of the spring-boot.jar located under BOOT-INF/lib : verification fails as there’s no hash available for the class in the manifest.

Thus, usage of the Spring Boot plugin for JAR creation/launch is not compatible with JAR signing.

The workaround

Aside from Spring Boot, there’s a legacy way to create standalone JARs: the Maven Shade plugin. This will extract every class of every dependency in the final JAR. This is possible with Spring Boot apps, but it requires some slight changes to the POM:

  1. In the POM, remove the Spring Boot Maven plugin
  2. Configure the main class in the Maven JAR plugin:
  maven-jar-plugin 3.0.2    org.springframework.samples.petclinic.PetClinicApplication    
  maven-shade-plugin 2.4.3  true    package  shade    
The command-line to launch the JAR doesn’t change but permissions depend on the executed code, coupled to the JAR structure. Hence, the policy file should be slightly modified.

Lessons learned

While it requires to be a little creative, it’s entirely possible to sign Spring Boot JARs by using the same techniques as for any other JARs.

To go further:

Nicolas Fränkel

Nicolas Fränkel

Developer Advocate with 15+ years experience consulting for many different customers, in a wide range of contexts (such as telecoms, banking, insurances, large retail and public sector). Usually working on Java/Java EE and Spring technologies, but with focused interests like Rich Internet Applications, Testing, CI/CD and DevOps. Also double as a trainer and triples as a book author.

Jvm

ElasticSearch API cheatsheet

ElasticSearch documentation is exhaustive, but the way it’s structured has some room for improvement. This post is meant as a cheat-sheet entry point into ElasticSearch APIs.

Nicolas Fränkel

Proposal for a Java policy files crafting process

This is the 2nd post in the JVM Security focus series. I’ve already written about the JVM security manager, and why it should be used — despite it being rarely the case, if ever. However, just advocating for it won’t change the harsh reality unless some guidelines are provided to do so. This post has the ambition to be the basis of such guidelines. As a reminder, the JVM can run in two different modes, standard and sandboxed. In the former, all API are available with no restriction; i

Nicolas Fränkel

Источник

Enhancing Security with Manifest Attributes

The following JAR file manifest attributes are available to help ensure the security of your applet or Java Web Start application. Only the Permissions attribute is required.

  • The Permissions attribute is used to ensure that the application requests only the level of permissions that is specified in the applet tag or JNLP file used to invoke the application. Use this attribute to help prevent someone from re-deploying an application that is signed with your certificate and running it at a different privilege level. This attribute is required in the manifest for the main JAR file. See Permissions Attribute in the Java Platform, Standard Edition Deployment Guide for more information.
  • The Codebase attribute is used to ensure that the code base of the JAR file is restricted to specific domains. Use this attribute to prevent someone from re-deploying your application on another website for malicious purposes. See Codebase Attribute in the Java Platform, Standard Edition Deployment Guide for more information.
  • The Application-Name attribute is used to provide the title that is shown in the security prompts for signed applications. See Application-Name Attribute in the Java Platform, Standard Edition Deployment Guide for more information.
  • The Application-Library-Allowable-Codebase attribute is used to identify the locations where your application is expected to be found. Use this attribute to reduce the number of locations shown in the security prompt when the JAR file is in a different location than the JNLP file or the HTML page. See Application-Library-Allowable-Codebase Attribute in the Java Platform, Standard Edition Deployment Guide for more information.
  • The Caller-Allowable-Codebase attribute is used to identify the domains from which JavaScript code can make calls to your application. Use this attribute to prevent unknown JavaScript code from accessing your application. See Caller-Allowable-Codebase Attribute in the Java Platform, Standard Edition Deployment Guide for more information.
  • The Entry-Point attribute is used to identify the classes that are allowed to be used as entry points to your RIA. Use this attribute to prevent unauthorized code from being run from other available entry points in the JAR file. See Entry-Point Attribute in the Java Platform, Standard Edition Deployment Guide for more information.
  • The Trusted-Only attribute is used to prevent untrusted components from being loaded. See Trusted-Only Attribute in the Java Platform, Standard Edition Deployment Guide for more information.
  • The Trusted-Library attribute is used to allow calls between privileged Java code and sandbox Java code without prompting the user for permission. See Trusted-Library Attribute in the Java Platform, Standard Edition Deployment Guide for more information.

See Modifying a Manifest File for information on adding these attributes to the manifest file.

Источник

Читайте также:  Php coded by exe
Оцените статью