Caching crypto objects to improve the performance when using the same crypto
for signing and encrypting.
--------------------------------------------------------------------------------------------------------
Key: RAMPART-248
URL: https://issues.apache.org/jira/browse/RAMPART-248
Project: Rampart
Issue Type: Improvement
Components: rampart-core
Affects Versions: 1.4
Reporter: Thilina Buddhika
Assignee: Ruchith Udayanga Fernando
Fix For: 1.5
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
ctCrypto.java:109)
at org.apache.ws.security.components.crypto.Merlin.<init>(Merlin.java:72
)
at sun.reflect.GeneratedConstructorAccessor234.newInstance(Unknown Sourc
e)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Sou
rce)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at org.apache.ws.security.components.crypto.CryptoFactory.loadClass(Cryp
toFactory.java:211)
at org.apache.ws.security.components.crypto.CryptoFactory.getInstance(Cr
yptoFactory.java:93)
at org.apache.rampart.util.RampartUtil.getSignatureCrypto(RampartUtil.ja
va:398)
at org.apache.rampart.PolicyBasedResultsValidator.verifyTrust(PolicyBase
dResultsValidator.java:601)
at org.apache.rampart.PolicyBasedResultsValidator.validate(PolicyBasedRe
sultsValidator.java:163)
at org.apache.rampart.RampartEngine.process(RampartEngine.java:214)
at org.apache.rampart.handler.RampartReceiver.invoke(RampartReceiver.jav
a:92)
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:signatureCrypto>
<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>
</ramp:signatureCrypto>
<ramp:encryptionCypto>
<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>
</ramp:crypto>
</ramp:encryptionCypto>
</ramp:RampartConfig>
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 ?
Thanks.
/ thilina
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.