Enhancements and new features in #XACML 3.0

I recently had a chat with the editor of XACML 3.0, Erik Rissanen – also the CTO of Axiomatics – about the latest news on XACML 3.0: the enhancements the standard has gone through and the new features we can look forward to.

  • Multiple Decision Profile: Multiple resource request (XACML 2.0) was renamed Multiple Decision Profile (XACML 3.0) and enhanced with new variants. This profile lets a requestor –typically the Policy Enforcement Point (PEP) ask several questions in one go to which the Policy Decision Point (PDP) returns one answer with multiple decisions. This profile is particularly useful in web-portal-based scenarios where decisions have to be reached for different parts of a portal within a given page for a given user. It enhances performance as it reduces communication overhead between PEP and PDP.
  • Delegation: the ability to delegate administrative rights in XACML is new as of XACML 3.0. Delegation enables global administrators to delegate constrained administrative rights to local administrators. For instance, a global administrator can define access control (AC) policies for an entire set of resources within an organization. The administrator can also delegate the right to Administrator A to manage a set of resources SA. Administrator A’s rights to define access control rules are constrained by the delegation policy that the global administrator has defined.
    Delegation is most useful in federation scenarios, cloud-based scenarios, and in environments where the domains to secure are so vast that they require local knowledge to define relevant policies.
  • Obligation expressions: this new feature lets administrators define statements that are returned from the PDP to the PEP along with a PERMIT or DENY decision. The receiving PEP has to comply with that statement before it can act on the decision. An example of an obligation is as follows:
    • Request: Can Doctor X access Patient Y’s data?
    • Response: Permit, he can, provided you, the PEP, write in the hospital access log, the fact that Doctor X has had access to Patient Y’s data.
  • Advice expressions: this new feature is similar to obligations with the exception that PEPs do not have to comply with the statement. PEPs can consider or discard the statement.
  • Policy combination algorithms: in XACML, policies are combined together to produce a single decision. Each policy can reach different decisions. These decisions must be combined to return a single result. XACML 3.0 enhances XACML 2.0’s existing combination algorithms.
  • New attribute functions and datatypes: XACML 3.0 brings in new datatypes and new functions that can be used for the attributes and attribute matching. In particular XACML 3.0 utilizes XPath to manipulate attributes.
  • New profiles: XACML 3.0 brings additional profiles. In particular a new profile for export compliance has been produced to help author policies that can cater for export compliance scenarios. Similarly, a new profile for Intellectual Property Control (IPC) has been introduced.
  • Enhanced profiles: the Hierarchical Resource Profile present in XACML 2.0 has been reviewed and enhanced in XACML 3.0.

Erik also told me that Axiomatics‘ latest product release implements XACML 3.0 and therefore contains the aforementioned features & enhancements.

#XACML Architecture Implementations should be modular

The XACML architecture puts forward keywords such as PEP, PDP, PAP, PIP, and PRP. But it does not recommend how to implement each one let alone how to best make them interact together.

The XACML architecture puts forward keywords such as PEP, PDP, PAP, PIP, and PRP. But it does not recommend how to implement each one let alone how to best make them interact together.

When customers decide to externalize their authorization and to go for a standards-based solution, namely a XACML-based solution, they need to be extremely careful how the vendor implements XACML. It is not just about implementing XACML’s request-response protocol. It is not just about authoring policies natively in XACML. It is also about implementing in an elegant, efficient, and modular way the XACML architecture.

The latter contains several key components as listed hereafter:

1. Firstly, the Policy Decision Point (PDP): this is where policies are evaluated and a decision is reached.

2. Secondly, the Policy Enforcement Point: this is where the request is created sent to the PDP and the response received and handled. The PEP can be application-specific.

3. Thirdly the Policy Retrieval Point (PRP) and the Policy Information Point (PIP) are two key components the PDP needs to retrieve policies and retrieve attributes respectively.

The way your vendor’s PDP implementation interacts with PEP, PRP, and PIP will determine how flexible their architecture is and how costly a deployment might turn out to be both in terms of non-capital investment (professional services, human resources) and in terms of capital investment (new hardware? new software? licenses?)

You should try to aim for a light-weight and flexible vendor that can provide a modular architecture where each component (PEP, PDP, PRP, PIP) can be taken individually, ripped from the others, dropped into new environments, and adapt to new components / deployments.

There is another XACML component to be considered: the Policy Administration Point (PAP). This component should provide (a) an interface to manage XACML policies and their lifecycle and (b) a XACML-aware client to facilitate the policy-authoring task.

Again, the way the PAP interacts with the other components should be flexible and modular. One should be able to run the PAP remotely or even perhaps without some of the other components.

The modularity and flexibility of the architecture will impact greatly performance as Gerry Gebel explains in one of his myth-busting posts on XACML.

#EIC2010: The Anywhere Architecture is Any-Depth too

In a recent keynote (Six Sigma For the Secure Cloud – Equip the Enterprise for Success) at the European Identity Conference, Gerry Gebel introduced the concept of the Anywhere Archictecture:

Data, applications and users can be anywhere… Does your architecture allow it? “Anywhere Architecture” is required.

The whole world is your market place and you need the flexibility that you could deploy [services] anywhere.

The Anywhere Architecture is about deploying services and connecting to users and data wherever they might be and enabling these interactions securely. Of course, in such a distributed environment, security needs to be rethought from the ground up. This goes through federated identity, trust establishment, externalized security, and flexible authorization to name but a few items. (More on Gerry’s blog)

“Anywhere Architecture” goes hand-in-hand with what I would call the any-depth architecture. Not only do you want to secure applications, data, and users wherever they might be, but you also want to achieve security at the right level, or depth, in order to exploit the relevant context in your security decision making.

In particular, when it comes to access control and authorization, it is important to be able to understand the context of the authorization decision making. Are we dealing with a service? A document? If so, does the access control apply to the entire document? Part of the document?

Any-depth architecture has two aspects. Firstly from a technical perspective, the any-depth architecture requires different connectors depending on the depth and technology of the integration. Are we integrating authorization (or more generally security) at a web service level? An ESB level? A legacy database level? Or even lower? Each level will require a specific integration point which in the XACML architecture is known as Policy Enforcement Point (PEP).

Any-depth architecture also has a business perspective and this is where context comes into play. Often customers will ask whether our Authorization service can take into account information of a document they wish to protect. The answer usually is that we can provided we integrate at the right level. Take for instance a Document Management System – a cloud-based one like Google Docs. If one wants to make decisions based on document information, then the integration with Google Docs must happen at the level of the API where the information is readily available. If on the other hand, one wants to make decisions based on the transport protocol (UDP vs. TCP for instance) then integration may need to take place at a lower level.

With Axiomatics’s Policy Server (APS), it becomes easy to integrate authorization at any of these levels. From a technical perspective, because the authorization engine is externalized and because it implements the XACML request/response protocol, the engine can be called by a PEP which has been specially crafted for a particular depth. From a business perspective, because the APS implements XACML and because XACML is attribute-based, one can take any information tidbit and map it to a XACML attribute. Both the PEP and the PDP can do this in a standard way through the Policy Information Point (PIP) interface.

And to summarize, here’s a little picture I wrote in SVG (an XML standard!) and XACML:

Integrate the Authorization Solution at the depth that is most relevant to your architecture.

Integrate the Authorization Solution at the depth that is most relevant to your architecture.

Securing web apps – Extend your gateways with fine-grained access control

Increasingly enterprises need to / want to expose their applications to the outside – be it the public internet with consumers or a virtual network of distributed enterprise sites accessing corporate resources.

Either way, to securely expose web applications, it is common practice to offer access via a DMZ which is protected by a firewall on the one hand (which handles network-level security) and an XML application gateway (which handles XML security, message transformation, routing, endpoint virtualization…)

The application gateway also has 2 security-critical missions: (a) authenticate the requestor and (b) authorize the request. The former is easily achieved by integrating with the authentication solution (e.g. an LDAP) and picking up the credentials from the request (username/password, certificates…). The latter has so far often been achieved as a consequence of authentication and of the products used. Authorization would then be a simple role-based access control where roles, user groups, and application groups would all be maintained in the authentication solution.

It is now possible though to fully utilize XACML-based, attribute-based authorization by integrating an application gateway with a XACML PDP engine e.g. the Axiomatics Policy Server. It is – as a matter of fact – what is described in this whitepaper on the integration between the APS and Intel’s SOA Expressway.

The following scribbling summarizes how simple the integration is.

Exposing applications securely - combining a firewall, an application gateway, and a XACML PDP

Exposing applications securely - combining a firewall, an application gateway, and a XACML PDP

The example in the picture considers a user, Bob, who wants to use a service S within a protected domain. Service S is exposed via a firewall and an application gateway (typically an XML security gateway). Bob requests Service S. The request goes through the firewall and is intercepted by the application gateway. The latter takes the request, extracts Bob’s credentials, and sends them on to the user directory (AD in the picture) for authentication (AuthN) (1). Once this step has completed and Bob has been authenticated, the gateway can now ask for an authorization decision from the XACML PDP (2). This allows for finer-grained authorization than what can be simply achieved with AD roles and groups. The gateway builds the XACML request to which it can add information extracted from

  • the incoming request (e.g. the action requested),
  • the user directory (e.g. Bob’s job title, clearance level) which then acts as a policy information point
  • the context / environment e.g. the time / location of the request

These information bits are converted to XACML attributes and added to the XACML request which is then sent by the gateway to the PDP for an authorization decision. If the decision is PERMIT, then the gateway can route Bob’s request to the service in step (3).

Integration can be easily achieved through the use of the XACML request/response protocol and because application gateways can naturally produce and consume XML messages.

XACML Scribblings at Infosec 2010

While at Infosec, I scribbled a few diagrams to explain how the APS can easily integrate with XML security gateways and AuthN solutions e.g. LDAP

While at Infosec, I scribbled a few diagrams to explain how the APS can easily integrate with XML security gateways and AuthN solutions e.g. LDAP

Export PKCS12 files to PEM format using OpenSSL

Not all applications use the same certificate format. Sometimes, it is necessary to convert between the different key / certificates formats that exist.

Some interesting resources online to figure that out are:
(a) OpenSSL’s homepage and guide
(b) Keytool’s user reference

In our scenario here we have a PKCS12 file which is a private/public key pair widely used, at least on Windows platforms. We want to convert to another format, namely PEM.

OpenSSL does that very nicely:

openssl pkcs12 -in alice.p12 -passin pass:password -out alice.pem

You will need to have openssl installed. It works on either Windows or Linux.

  • The -in option specifies what file to read the keys / certificates from. This is our PKCS12 file.
  • -passin lets the user specify the password protecting the source PKCS12 file.
  • The prefix pass: is what OpenSSL documentation calls a passphrase argument. It indicates that what follows the colon is the actual password value, in this case ‘password’.
  • -out indicates which file to save the result to (the result being in this case both the public and private keys of alice). The default output format is PEM so we don’t need to specify anything else.

The result of this command is printed hereafter. It asks the user for a password to protect the PEM file.

MAC verified OK
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:

You can use your favorite editor (VI, Notepad, or less) to view the contents of alice.pem which will look like

Bag Attributes
    localKeyID: 28 B5 8E 16 11 88 E9 00 58 D5 76 30 12 B9 59 B8 E4 CE 7C AA
subject=/C=UK/ST=Suffolk/L=Ipswich/O=Example plc/CN=alice
issuer=/C=UK/ST=Suffolk/L=Ipswich/O=Example plc/CN=Certificate Authority/emailAddress=ca@example.com
-----BEGIN CERTIFICATE-----
MIIDDzCCAfegAwIBAgIJAMkyzQVK88NHMA0GCSqGSIb3DQEBBQUAMIGCMQswCQYD
VQQGEwJTRTESMBAGA1UECBMJU3RvY2tob2xtMQ4wDAYDVQQHEwVLaXN0YTEQMA4G
[...]
0fbkqbKulrchGbNgkankZtEVg4PGjo+Y8MdMjtfSZB29hwYvfMX09jzJ68ZqmpYQ
njvcVtLbEZN5OGCkaslb/f2OxLbsUNgIbws538WnaaufDvKmQe2kUdWmpl9Wn9Bf
bZq7B+njvcVa7SsWF/WLq5AUbw==
-----END CERTIFICATE-----
Bag Attributes
    localKeyID: 28 B5 8E 16 11 88 E9 00 58 D5 76 30 12 B9 59 B8 E4 CE 7C AA
Key Attributes:
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,59E17A0681CBBA5A

h8cxvZIwq+91bmRZ98eVsd0JHV1JKBRCSIrCs596npOTZD0gN5cD16HkqqBmaoRK
[...]
buaa7eUVtGawy3zn1bZsRcTPMXsPyqhpx6WtjkVb1P37QYPx4n1LgNcYGsOMAXOE
F+9wWVx0NuoV4guDrENm3/rCwhBC70Kh2G0234hf+10=
-----END RSA PRIVATE KEY-----

Securing web services with Metro – com.sun.xml.wss.impl.XWSSecurityRuntimeException: PrivateKey returned by PrivateKeyCallback was Null

Typical exception:
PrivateKey returned by PrivateKeyCallback was Null

SEVERE: WSS1417: Error while processing signature java.lang.RuntimeException: com.sun.xml.wss.impl.XWSSecurityRuntimeException: PrivateKey returned by PrivateKeyCallback was Null
09-Apr-2010 10:27:09 com.sun.xml.wss.jaxws.impl.SecurityTubeBase secureOutboundMessage
SEVERE: WSSTUBE0024: Error in Securing Outbound Message.
com.sun.xml.wss.XWSSecurityException: com.sun.xml.wss.XWSSecurityException: java.lang.RuntimeException: com.sun.xml.wss.impl.XWSSecurityRuntimeException: PrivateKey returned by PrivateKeyCallback was Null
	at com.sun.xml.wss.impl.filter.SignatureFilter.process(SignatureFilter.java:241)
	at com.sun.xml.wss.impl.HarnessUtil.processWSSPolicy(HarnessUtil.java:93)
	at com.sun.xml.wss.impl.HarnessUtil.processDeep(HarnessUtil.java:268)
	at com.sun.xml.wss.impl.SecurityAnnotator.processMessagePolicy(SecurityAnnotator.java:186)
	at com.sun.xml.wss.impl.SecurityAnnotator.secureMessage(SecurityAnnotator.java:147)
	at com.sun.xml.wss.jaxws.impl.SecurityTubeBase.secureOutboundMessage(SecurityTubeBase.java:346)
	at com.sun.xml.wss.jaxws.impl.SecurityClientTube.processClientRequestPacket(SecurityClientTube.java:236)
	at com.sun.xml.wss.jaxws.impl.SecurityClientTube.processRequest(SecurityClientTube.java:167)
	at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:598)
	at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:557)
	at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:542)
	at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:439)
	at com.sun.xml.ws.client.Stub.process(Stub.java:222)
	at com.sun.xml.ws.client.sei.SEIStub.doProcess(SEIStub.java:135)
	at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:109)
	at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:89)
	at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:118)
	at $Proxy48.instanceAccessQuery3(Unknown Source)
	at eu.webfarmr.servlet.ws.WSConnection.evaluate(WSConnection.java:156)
	at eu.webfarmr.servlet.ServletEnforcer.enforce(ServletEnforcer.java:150)
	at eu.webfarmr.servlet.AuthFilter.doFilter(AuthFilter.java:133)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:558)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
	at java.lang.Thread.run(Thread.java:619)
Caused by: com.sun.xml.wss.XWSSecurityException: java.lang.RuntimeException: com.sun.xml.wss.impl.XWSSecurityRuntimeException: PrivateKey returned by PrivateKeyCallback was Null
	at com.sun.xml.wss.impl.misc.DefaultSecurityEnvironmentImpl.getDefaultPrivKeyCertRequest(DefaultSecurityEnvironmentImpl.java:233)
	at com.sun.xml.wss.impl.filter.SignatureFilter.process(SignatureFilter.java:156)
	... 33 more
Caused by: java.lang.RuntimeException: com.sun.xml.wss.impl.XWSSecurityRuntimeException: PrivateKey returned by PrivateKeyCallback was Null
	at com.sun.xml.wss.impl.misc.DefaultCallbackHandler.getDefaultPrivKeyCert(DefaultCallbackHandler.java:1359)
	at com.sun.xml.wss.impl.misc.DefaultCallbackHandler.handle(DefaultCallbackHandler.java:520)
	at com.sun.xml.wss.impl.misc.DefaultSecurityEnvironmentImpl.getDefaultPrivKeyCertRequest(DefaultSecurityEnvironmentImpl.java:228)
	... 34 more
Caused by: com.sun.xml.wss.impl.XWSSecurityRuntimeException: PrivateKey returned by PrivateKeyCallback was Null
	at com.sun.xml.wss.impl.misc.DefaultCallbackHandler.getPrivateKey(DefaultCallbackHandler.java:2198)
	at com.sun.xml.wss.impl.misc.DefaultCallbackHandler.getDefaultPrivKeyCert(DefaultCallbackHandler.java:1350)
	... 36 more
09-Apr-2010 10:27:09 com.sun.xml.wss.jaxws.impl.SecurityClientTube processClientRequestPacket
SEVERE: WSSTUBE0024: Error in Securing Outbound Message.
com.sun.xml.wss.impl.WssSoapFaultException: com.sun.xml.wss.XWSSecurityException: java.lang.RuntimeException: com.sun.xml.wss.impl.XWSSecurityRuntimeException: PrivateKey returned by PrivateKeyCallback was Null
	at com.sun.xml.wss.impl.SecurableSoapMessage.newSOAPFaultException(SecurableSoapMessage.java:337)
	at com.sun.xml.wss.jaxws.impl.SecurityTubeBase.secureOutboundMessage(SecurityTubeBase.java:353)
	at com.sun.xml.wss.jaxws.impl.SecurityClientTube.processClientRequestPacket(SecurityClientTube.java:236)
	at com.sun.xml.wss.jaxws.impl.SecurityClientTube.processRequest(SecurityClientTube.java:167)
	at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:598)
	at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:557)
	at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:542)
	at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:439)
	at com.sun.xml.ws.client.Stub.process(Stub.java:222)
	at com.sun.xml.ws.client.sei.SEIStub.doProcess(SEIStub.java:135)
	at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:109)
	at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:89)
	at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:118)
	at $Proxy48.instanceAccessQuery3(Unknown Source)
	at eu.webfarmr.servlet.ws.WSConnection.evaluate(WSConnection.java:156)
	at eu.webfarmr.servlet.ServletEnforcer.enforce(ServletEnforcer.java:150)
	at eu.webfarmr.servlet.AuthFilter.doFilter(AuthFilter.java:133)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:558)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
	at java.lang.Thread.run(Thread.java:619)
Caused by: com.sun.xml.wss.XWSSecurityException: com.sun.xml.wss.XWSSecurityException: java.lang.RuntimeException: com.sun.xml.wss.impl.XWSSecurityRuntimeException: PrivateKey returned by PrivateKeyCallback was Null
	at com.sun.xml.wss.impl.filter.SignatureFilter.process(SignatureFilter.java:241)
	at com.sun.xml.wss.impl.HarnessUtil.processWSSPolicy(HarnessUtil.java:93)
	at com.sun.xml.wss.impl.HarnessUtil.processDeep(HarnessUtil.java:268)
	at com.sun.xml.wss.impl.SecurityAnnotator.processMessagePolicy(SecurityAnnotator.java:186)
	at com.sun.xml.wss.impl.SecurityAnnotator.secureMessage(SecurityAnnotator.java:147)
	at com.sun.xml.wss.jaxws.impl.SecurityTubeBase.secureOutboundMessage(SecurityTubeBase.java:346)
	... 28 more
Caused by: com.sun.xml.wss.XWSSecurityException: java.lang.RuntimeException: com.sun.xml.wss.impl.XWSSecurityRuntimeException: PrivateKey returned by PrivateKeyCallback was Null
	at com.sun.xml.wss.impl.misc.DefaultSecurityEnvironmentImpl.getDefaultPrivKeyCertRequest(DefaultSecurityEnvironmentImpl.java:233)
	at com.sun.xml.wss.impl.filter.SignatureFilter.process(SignatureFilter.java:156)
	... 33 more
Caused by: java.lang.RuntimeException: com.sun.xml.wss.impl.XWSSecurityRuntimeException: PrivateKey returned by PrivateKeyCallback was Null
	at com.sun.xml.wss.impl.misc.DefaultCallbackHandler.getDefaultPrivKeyCert(DefaultCallbackHandler.java:1359)
	at com.sun.xml.wss.impl.misc.DefaultCallbackHandler.handle(DefaultCallbackHandler.java:520)
	at com.sun.xml.wss.impl.misc.DefaultSecurityEnvironmentImpl.getDefaultPrivKeyCertRequest(DefaultSecurityEnvironmentImpl.java:228)
	... 34 more
Caused by: com.sun.xml.wss.impl.XWSSecurityRuntimeException: PrivateKey returned by PrivateKeyCallback was Null
	at com.sun.xml.wss.impl.misc.DefaultCallbackHandler.getPrivateKey(DefaultCallbackHandler.java:2198)
	at com.sun.xml.wss.impl.misc.DefaultCallbackHandler.getDefaultPrivKeyCert(DefaultCallbackHandler.java:1350)
	... 36 more

The reason may lie in the private key used. In this case the configuration contains the following lines:

servlet.keystore = O:/cygwin/home/djob/truststore.jks
servlet.keystore.password = changeit
servlet.keystore.alias = alice
servlet.keystore.type = JKS

We are trying to use a private key stored in truststore.jks. This private key is identified by its alias, alice. Both key and keystore can / are protected by a password. In this configuration. it is expected that the keystore be protected by the password changeit but what is not explicitly said is that the private key should also have the same password. How can we make sure it is the case?

Let’s use keytool and explore the keystore, truststore.jks:

  1. List the private keys contained in the store and check that there is one with an alias ‘alice’
    O:\cygwin\home\djob>keytool -v -list -keystore truststore.jks

    This prints out the following

    Keystore type: JKS
    Keystore provider: SUN
    
    Your keystore contains 1 entry
    
    Alias name: wrong-alias
    Creation date: 09-Apr-2010
    Entry type: PrivateKeyEntry
    Certificate chain length: 1
    Certificate[1]:
    Owner: CN=alice, O=Example AB
    Issuer: EMAILADDRESS=ca@example.com, CN=Certificate Authority, O=Example
    Serial number: c932cd054af3c347
    Valid from: Wed Aug 19 10:25:07 CEST 2009 until: Sat Aug 17 10:25:07 CEST 2019
    Certificate fingerprints:
             MD5:  71:17:DF:E0:31:5D:D2:3B:F1:FD:C2:96:E7:AE:28:12
             SHA1: 28:B5:8E:16:11:88:E9:00:58:D5:76:30:12:B9:59:B8:E4:CE:7C:AA
             Signature algorithm name: SHA1withRSA
             Version: 3
    
    Extensions:
    
    #1: ObjectId: 2.5.29.14 Criticality=false
    SubjectKeyIdentifier [
    KeyIdentifier [
    0000: 8C 89 33 CF 1C 6B 40 48   05 7C F5 E6 2C AB 6B 8F  ..3..k@H....,.k.
    0010: 3E 68 9B E4                                        >h..
    ]
    ]
    
    #2: ObjectId: 2.5.29.19 Criticality=false
    BasicConstraints:[
      CA:false
      PathLen: undefined
    ]
    
    #3: ObjectId: 2.5.29.35 Criticality=false
    AuthorityKeyIdentifier [
    KeyIdentifier [
    0000: C3 D4 7E 81 FA E1 0F 36   F5 B8 F1 44 0C 4C B9 A1  .......6...D.L..
    0010: BB 09 5C 1D                                        ..\.
    ]
    
    ]
    
    #4: ObjectId: 2.16.840.1.113730.1.13 Criticality=false
    
    *******************************************
    *******************************************
  2. If the alias is wrong, change it. As you can see in the previous example, the alias is ‘wrong-alias’ rather than ‘alice’.
    O:\cygwin\home\djob>keytool -v -changealias -alias wrong-alias -destalias alice -keystore truststore.jks

    . This will ask for the keystore certificate ‘changeit’. It prints out

    Enter keystore password:
    [Storing O:/cygwin/home/djob/truststore.jks]
  3. Make sure the key password is the same as the keystore password. Simply update the key password to that of the store.
    O:\cygwin\home\djob>keytool -v -keypasswd -keystore truststore.jks -alias alice

    This will ask for the keystore certificate ‘changeit’, the key’s old password and new password which you should set to the same as the store (changeit). It prints out

    Enter keystore password:
    Enter key password for <alice>
    New key password for <alice>:
    Re-enter new key password for <alice>:
    [Storing O:/cygwin/home/djob/truststore.jks]

    Note that if key password and store password were already the same, then when running the command aforementioned, it will not ask for key password. This is therefore an indication you need not change your key password.

Import PKCS12 private keys into JKS keystores using Java Keytool

This is very simple yet when I googled around I saw erratic answers such as ‘it is not possible’ or ‘you have to write java code’.

As a matter of fact, keytool (a key management utility shipped in Sun’s JDK) lets you do it simply.

  • What do you want to do?
    Convert alice.p12 to alice.jks
  • Why do you want to do that?
    In Metro, a WS stack, it is common to use JKS as a format for storing private keys
  • How do you convert then?
    See below


Keytool’s documentation refers to the following option

-importkeystore [-v]
             [-srckeystore ] [-destkeystore ]
             [-srcstoretype ] [-deststoretype ]
             [-srcstorepass ] [-deststorepass ]
             [-srcprotected] [-destprotected]
             [-srcprovidername ]
             [-destprovidername ]
             [-srcalias  [-destalias ]
               [-srckeypass ] [-destkeypass ]]
             [-noprompt]
             [-providerclass
 [-providerarg ]] ...
             [-providerpath
]

So in fact in our case, converting from alice.p12 to alice.jks is extremely simple:

  1. Create an empty JKS store
    keytool -genkey -alias alice -keystore alice.jks
    keytool -delete -alias alice -keystore alice.jks
  2. Import alice.p12 into alice.jks
    keytool -v -importkeystore -srckeystore alice.p12 -srcstoretype PKCS12 -destkeystore truststore.jks -deststoretype JKS