web-dev-qa-db-fra.com

Besoin d'un thread sécurisé MessageDigest dans Java

J'ai besoin de hacher plusieurs clés de plusieurs threads à l'aide de MessageDigest dans un environnement critique pour les performances. J'ai appris que MessageDigest n'est pas thread-safe car il stocke son état dans son objet. Quelle peut être la meilleure façon possible de réaliser un hachage sûr des threads?

Cas d'utilisation:

MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");

//somewhere later, just need to hash a key, nothing else
messageDigest.update(key);
byte[] bytes = messageDigest.digest(); 

Plus précisément:

  1. Est-ce que ThreadLocal est garanti pour fonctionner? Y aura-t-il une pénalité de performance?
  2. Les objets retournés par getInstance sont-ils différents et n'interfèrent-ils pas entre eux? La documentation dit "nouvel" objet, mais je ne sais pas si c'est juste un wrapper sur une classe concrète partagée (partagée)?
  3. Si getInstance () retourne de "vrais" nouveaux objets, est-il conseillé de créer une nouvelle instance chaque fois que j'ai besoin de calculer le hachage? En termes de pénalité de performance - quel est le coût?

Mon cas d'utilisation est très simple - il suffit de hacher une clé simple. Je ne peux pas me permettre d'utiliser la synchronisation.

Merci,

26
Anil Padia

Créez une nouvelle instance de MessageDigest chaque fois que vous en avez besoin.

Toutes les instances renvoyées par getInstance() sont distinctes. Ils doivent l'être, car ils maintiennent des résumés séparés (et si cela ne vous suffit pas, voici un lien vers la source).

ThreadLocal peut fournir un avantage de performance lorsqu'il est utilisé avec un threadpool, pour maintenir des objets coûteux à construire. MessageDigest n'est pas particulièrement cher à construire (encore une fois, regardez la source).

41
parsifal

Comme alternative, utilisez DigestUtils , le wrapper thread-safe d'Apache Commons pour MessageDigest.

sha1 () fait ce dont vous avez besoin:

byte[] bytes = sha1(key)

5
fishyfriend

DigestUtils ne semble pas être plus sûr pour les threads que MessageDigest brut. Utilise toujours MessageDigest.getInstance sous les couvertures.

1
Big Kahuna