[PATCH] Add class java.security.StandardMessageDigests
Florian Weimer
fweimer at redhat.com
Tue May 6 12:06:29 UTC 2014
On 05/06/2014 01:39 PM, Xuelei Fan wrote:
> Another concern of mine is about that the returned MessageDigest object
> heavily depends on the providers configuration when the object get
> instantiated for the 1st time. If the providers configuration get
> updated during run time, the provider of the returned MessageDigest
> object does not get updated accordingly. This proposal may be a pretty
> good practice in application layer in some circumstance, but may result
> in unnecessary complexity in JRE layer because we don't know the exact
> context that the application want to use this class, and the exact
> implementation details of the underlying MD service provider.
Hmm. It would certainly be possible to invalidate the cache if the
provider configuration is changed.
It's unlikely that a library-based reimplementation could get this right.
> Per the spec, clone() may throw CloneNotSupportedException. It is OK a
> certain provider does not support Cloneable.
The key part is that the behavior has to be consistent across all
objects. It's not required that clone() works, but if it works for one
instance, it works for all of them.
>> The
>> TLS implementation also relies on this behavior (i.e. clone() either
>> consistently fails or consistently succeeds).
>>
> That's true. SunJSSE requires cloneable MD implementation.
Are you sure? It contains a fairly elaborate workaround for the
non-cloneable case (construct as many digest objects as needed, and then
feed them data in parallel so that you can finalize one pseudo-clone,
but continue hashing using the other one).
> If the performance can get improvement here by define a static cloneable
> object, it might be also can get improvement in the same way in the
> provider implementation, unless the improvement is all about
> implementation service look up among the supported providers.
It's the service lookup. Well, it was the service lookup in 2010.
>>> BTW! I guess in some situation or some providers, clone() might not be
>>> a lightweight operation.
>>
>> Hmm. I can see that the state cannot be cloned at all (that's why
>> cloning is optional), but allocating a new state has to happen anyway,
>> no matter how the object is constructed.
>>
> Let's consider a case, every MD object should be bound to a session, and
> the operations should be synchronized in the session. clone() will share
> the session, the operations among different MD objects that share the
> session need to be synchronized. I think, there is a significant
> performance and scalablity impact if StandardMessageDigests is used for
> such cases in concurrency context.
Why would clone() share the session, but constructing a new digest would
not? Because sharing the session would be the only way to share the
state? Ugh, yes, you might be right.
>> What I meant is that there might be no place to store the reference to a
>> long-term MessageDigest object which is reused again and again, so the
>> best thing the code can do is to allocate a fresh object when it is needed?
>>
> The object of MessageDigest is not immutable. IMHO, as we discussed
> above, there are a lot of issues need to be considered carefully to
> support such a long-term object in JRE.
I meant a method like this:
public static byte[] sha1(byte[] buffer, int offset, int length) {
MessageDigest md = threadLocalMDs.sha1();
md.update(buffer, offset, length);
return md.digest();
}
The actual digest object would not be exposed through this interface.
This would cover the use case of hashing short buffers, where the
instantiation overhead is most visible.
--
Florian Weimer / Red Hat Product Security Team
More information about the security-dev
mailing list