Java platform had a strong emphasis on security from the very beginning. The multi-platform support has made people sceptical about the way Java handles security aspects and if there are some hidden risks. Java is a type-safe language and provides automatic garbage collection. The use of secure class loading and verification mechanism allows only legitimate Java code to be executed. The initial version of Java platform was focused specifically on providing a safe environment for running potentially untrusted code, such as Java applets. With the growth in the platform and wide spread deployment, the Java security architecture has evolved to support the expanding set of services. Over the years, the architecture has grown to include a large set of APIs, tools and implementations of security algorithms, mechanisms and protocols. Java security revolves around two key aspects:
- Secure platform to run applications on.
- Tools and services available in the Java programming language that facilitate a range of security sensitive applications
Language Level Security
There are multiple mechanisms inbuilt within the Java language to ensure secure programming:
- Strictly Object-Oriented – All security related advantages of object oriented paradigm can be availed of as there can be no structures outside the boundary of a class.
- Final Classes and Methods – Undesired modification of functionality can be prevented by making classes and methods as final.
- Automated Memory Management – There are fewer chances of errors related to memory access as Java language does all the memory management automatically.
- Automatic Initialization – All memory constructs on heap are automatically initialized. However, all stack based memory is not pre-initialized. This makes sure that all classes and instances are never set undefined values.
Basic Security Architecture
There are a set of APIs spanning all the major security areas like cryptography, public key infrastructure, authentication, secure communication and access control. These APIs help in easy integration of security in application code. They are designed around the following principles:
- Implementation Independence – Application need not worry about the finer details of security and can request security from the Java platform. These security services are implemented in providers which get plugged into the Java platform via a standard interface. An application may leverage multiple independent providers for security.
- Implementation Interoperability – By their very nature, providers are interoperable across applications. Just like an application is not bound to a specific provider, similarly a provider is not bound to any specific application.
- Algorithm Extensibility – There are a number of built-in providers that implement a basic set of security services. There is a provision for installing custom providers which address specific needs of applications.
The concept of security provider is encapsulated by java.security.Provider class. It specifies the provider’s name and lists the security services it supports. It is possible to configure multiple providers at the same time and can be listed in order of preference. When a security service is requested, the provider with the highest priority is selected. Message digest creation is one type of service available from providers. An application can invoke getInstance method in the java.securityy.MessageDigest class to obtain an implementation of a specific message digest algorithm like MD5.
MessageDisgest md = MessageDigest.getInstance(“MD”);
Optionally, the provider name can be specified while requesting an implementation.
MessageDigest md = MessageDigest.getInstance(“MD5”, “ProviderA”);
Following figures illustrate these options for requesting an MD5 message digest implementation. Both the instances depict three providers that implement message digest algorithm. The providers are ordered by preference from left to right. In the first instance, an application can be seen requesting MD5 algorithm without specifying a provider name. The providers are looked for in preference order and the implementation from the first provider supplying that particular algorithm, ProviderB is returned. In second instance, the application requests the MD5 algorithm implementation from a specific provider, ProviderC. In this case, the implementation from that provider is returned, even though a provider with a higher preference order, ProviderB also supplies an MD5 implementation.
Figure – 1 – Provider Selection
Java provides a cryptography framework for accessing and developing cryptographic functionality for the Java platform. It includes APIs for a large variety of cryptographic services like Message digest algorithms, Digital signature algorithms, Symmetric stream encryption, Asymmetric encryption, etc. The cryptographic interfaces are provider-based which allows for multiple and interoperable cryptography implementations.
Public Key Infrastructure
The Public Key Infrastructure (PKI) framework enables secure exchange of information based on public key cryptography. It facilitates identities (of people, organizations, etc.) to be bound to digital certiﬁcates and provides a means of verifying the authenticity of certiﬁcates. PKI comprises of keys, certiﬁcates, public key encryption, and trusted Certiﬁcation Authorities (CAs) who generate and digitally sign certiﬁcates.
Authentication helps in identifying the user of an executing Java program. The Java platform provides APIs to perform user authentication via pluggable login modules.
It is quite important to ensure that the data that travels across a network is not accessed by an unintended recipient. In case the data includes private information, like passwords and credit card numbers, steps must be taken to make the data unintelligible to unauthorized parties. The Java platform provides API support and provider implementations for a number of standard secure communication protocols like SSL/TLS, SASL, GSS-API and Kerberos.
The access control architecture protects access to sensitive resources (for example, local ﬁles) or sensitive application code (for example, methods in a class). All access control decisions are mediated by a security manager, represented by the java.lang.SecurityManager class. A SecurityManager must be installed into the Java runtime in order to activate the access control checks.
Enhancements in JDK 8
JDK 8 has wide range of security related enhancements and features. Some of those are listed below:
TLS 1.1 and TLS 1.2 enabled by default
TLS 1.1 and TLS 1.2 are enabled by default on the client side by the SUNJSSE provider. You can enable SunJSSE protocols by using the new system property jdk.tls.client.protocols.
A new version of the method AccessController.doPrivileged can be used to assert a subset of its privileges, without preventing the full traversal of the stack to check for other permissions.
Stronger Algorithms for Password-Based Encryption
Many AES-based Password-Based Encryption (PBE) algorithms, such as PBEWithSHA256AndAES_128 and PBEWithSHA512AndAES_256, have been added to the SunJCE provider.
SSL/TLS Server Name Indication (SNI) Extension Support in JSSE Server
The SNI extension extends the SSL/TLS protocols to indicate what server name the client is attempting to connect to during handshaking. Servers can use server name indication information to decide if specific SSLSocket or SSLEngine instances should accept a connection. JDK 7 already has SNI extension enabled by default. JDK 8 supports the SNI extension for server applications.
A new command option – importpassword facilitates accepting a password and store it securely as a secret key. A new class, java.security.DomainLoadStoreParameter is added to support DKS keystore type.
SHA-224 Message Digests
JDK 8 has enhanced cryptographic algorithms with the SHA-224 variant of the SHA-2 family of message-digest implementations.
Improved Support for High Entropy Random Number Generation
The SecureRandom class helps in generating cryptographically strong random numbers used for private or public keys, ciphers, signed messages, and so on.
64-bit PKCS11 for Windows
The PKCS 11 provider support for Windows has been expanded to include 64-bit.
Weak Encryption Disabled by Default
The DES-related Kerberos 5 encryption types are not supported by default. These encryption types can be enabled by adding allow_wbeak_crypto=true in the krb5.conf file, but DES-related encryption types are considered highly insecure and should be avoided.
Unbound SASL for the GSS-API/Kerberos 5 mechanism
The Krb5LoginModule principal value in a JAAS configuration file can be set to asterisk (*) on the acceptor side to denote an unbound acceptor. This means that the initiator can access the server using any service principal name if the acceptor has the long term secret keys to that service. The name can be retrieved by the acceptor using the GSSContext.getTargName() method after the context is established.
SASL service for multiple host names
While creating a SASL server, the server name can be set to null to denote an unbound server, which means a client can request for the service using any server name.
Java 8 has taken a definitive step in making Java more secure by introducing these new security enhancements.