Uploaded image for project: 'Rampart'
  1. Rampart
  2. RAMPART-248

Caching crypto objects to improve the performance when using the same crypto for signing and encrypting.



    • Improvement
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 1.4
    • 1.5
    • rampart-core
    • None


      When a particular cryptographic operation is taken place, a crypto object is created for that operation. This process involves reading certificates from the file system each time a cryptographic operation is carried out. The situation gets worse when multiple threads are trying to invoke cryptographic operations that involves the same certificate. This may lead to race condition and ends up with an exception with the following stacktrace.

      at java.io.FileInputStream.open(Native Method)
      at java.io.FileInputStream.<init>(Unknown Source)
      at java.io.FileInputStream.<init>(Unknown Source)
      at org.apache.ws.security.components.crypto.AbstractCrypto.<init>(Abstra
      at org.apache.ws.security.components.crypto.Merlin.<init>(Merlin.java:72
      at sun.reflect.GeneratedConstructorAccessor234.newInstance(Unknown Sourc
      at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Sou
      at java.lang.reflect.Constructor.newInstance(Unknown Source)
      at org.apache.ws.security.components.crypto.CryptoFactory.loadClass(Cryp
      at org.apache.ws.security.components.crypto.CryptoFactory.getInstance(Cr
      at org.apache.rampart.util.RampartUtil.getSignatureCrypto(RampartUtil.ja
      at org.apache.rampart.PolicyBasedResultsValidator.verifyTrust(PolicyBase
      at org.apache.rampart.PolicyBasedResultsValidator.validate(PolicyBasedRe
      at org.apache.rampart.RampartEngine.process(RampartEngine.java:214)
      at org.apache.rampart.handler.RampartReceiver.invoke(RampartReceiver.jav
      at org.apache.axis2.engine.Phase.invoke(Phase.java:317)
      at org.apache.axis2.engine.AxisEngin

      So one possible solution for this is to implement crypto caching inside RampartUtil. This can be a hashtable which stores Crypto objects against a value of a unique property of a particular Crypto implementation. For example : If we take Merlin as the Crypto implementation, then "org.apache.ws.security.crypto.merlin.file" is the unique property for a particular Crypto object.
      So it is required to identify the unique properties for a particular Crypto implementation. Then enough attention should be paid to refresh the cache, since there is a possibility of changing the certs in the file system. One solution for this is to set a cache refresh interval and invalidate the cache after that interval. So the unique property and the cache refresh interval needs to be captured from the user. So these information can be included in RamaprtConfig.

      Solution :

      To enable caching of Crypto objects, two attributes should be added to the crypto elements of "signatureCrypto"/"encryptionCrypto" of RampartConfig.

      1.cryptoKey - As the value of this attribute, specify the property of a Crypto implementation which points to the location of the keystore. For example in Merlin, the property "org.apache.ws.security.crypto.merlin.file" is unique and its pointing to the location of the keystore. Absence of this attribute will not enable caching.

      2.cacheRefreshInterval - This is the cache refresh interval specified in milliseconds. Any object that resides in the cache longer than this period will be considered as expired. Cache will not be refreshed if this attribute is not present in the configuration. If you do not want to refresh the cache, provide only the "cryptoKey" attribute.

      So this is a sample of the suggested Ramapart Config.

      <ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
      <ramp:crypto provider="org.apache.ws.security.components.crypto.Merlin" cryptoKey="org.apache.ws.security.crypto.merlin.file" cacheRefreshInterval="300000">
      <ramp:property name="org.apache.ws.security.crypto.merlin.keystore.type">JKS</ramp:property>
      <ramp:property name="org.apache.ws.security.crypto.merlin.file">service.jks</ramp:property>
      <ramp:property name="org.apache.ws.security.crypto.merlin.keystore.password">servicePW</ramp:property>
      <ramp:crypto provider="org.apache.ws.security.components.crypto.Merlin" cryptoKey="org.apache.ws.security.crypto.merlin.file" cacheRefreshInterval="300000>
      <ramp:property name="org.apache.ws.security.crypto.merlin.keystore.type">JKS</ramp:property>
      <ramp:property name="org.apache.ws.security.crypto.merlin.file">service.jks</ramp:property>
      <ramp:property name="org.apache.ws.security.crypto.merlin.keystore.password">apache</ramp:property>

      A sample configuration is provided below. It uses the Merlin crypto implementation for signing and encryption. Here, the value of the cryptoKey attribute is eqaul to "org.apache.ws.security.crypto.merlin.file" and the cache refresh interval is 300000 milliseconds.

      I came with an implementation following the model explained above. his implementation is done in a backward compatible way and it will not break any of the current functionalities.

      WDYT ?

      / thilina


        1. crypto-caching.patch
          14 kB
          Thilina Mahesh Buddhika



            nandana.cse Nandana Mihindukulasooriya
            thilinamb Thilina Mahesh Buddhika
            0 Vote for this issue
            0 Start watching this issue