So, I’ve cruised through several Stackoverflow threads and other websites as well whilst trying to find a solution to this.
I am working on a school assignment that requires the use of an instance of MessageDigest.
I will paste my code below, but I have tried getInstance(“SHA-256”) and getInstance(“SHA-1”) and getInstance(“MD5”) all with the same error.
I have also tried adding the provider parameter with “SUN” but then I get a
NoSuchProviderException.
My school instructions call for import java.security.MessageDigest
.
I have tried that as well as import java.security.*
in case something was missing.
I have tried to get a list of providers but that does not give me anything and it won’t even compile.
I have followed the try/catch instructions found at this site. Still nothing.
I have no idea where to go next and none of the sites seems to have a solid answer for this.
According to Oracle, the process should cycle through providers until it finds one that supports whichever algorithm you selected, and I have tried all three on their list source.
I know it’s probably something super simple that I’m overlooking, but I can’t seem to get it straight. Any help would be appreciated. Code below
-Jon
Code:
package com.snhu.sslserver; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.security.MessageDigest; import java.util.Scanner; @SpringBootApplication public class ServerApplication { public static void main(String[] args) { SpringApplication.run(ServerApplication.class, args); } } @RestController class ServerController{ //create instance of message digest MessageDigest md = MessageDigest.getInstance("SHA-256"); //FIXME: Add hash function to return the checksum value for the data string that should contain your name. @RequestMapping("/hash") public String myHash(){ String data = "Hello Joe Smith!"; return "<p>data:"+data; } }
Advertisement
Answer
Independent Usage Issue
MessageDigest instances are not thread-safe. There is no thread-safety guarantee in the doc
Please do not use MessageDigest instance like this (unless your controller is request scoped)
Assumption
- Thread pools are used by the server
- Expectation is to reduce the overhead of MessageDigest object creation
Possible solution
- Create
ThreadLocal
instance ofMessageDigest
- compute digest using this
ThreadLocal
instance - Hopefully future
Fiber
s will honor this way of usage (if not, we have much bigger problem in java ecosystem)
Suggestion
In situations were threads are dynamically created/destroyed, and still the overhead of creating MessageDigest is considerable:
- Manage a separate executor service(with threadpool), and manage digest using futures
- or create new MessageDigest instance per request (to avoid unnecessary ThreadLocal overhead.