Describe the security issue
SHA1PRNG, the random number generator algorithim, used when setting user passwords does not work on FIPS-compliant systems.
Method failed: HTTP/1.1 500 Internal Server Error
com.mirth.connect.client.core.ClientException: Method failed: HTTP/1.1 500 Internal Server Error
at com.mirth.connect.client.core.ServerConnection.handleResponse(ServerConnection.java:533)
at com.mirth.connect.client.core.ServerConnection.executeSync(ServerConnection.java:257)
at com.mirth.connect.client.core.ServerConnection.apply(ServerConnection.java:167)
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:255)
at org.glassfish.jersey.client.JerseyInvocation$3.call(JerseyInvocation.java:722)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:718)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:459)
at org.glassfish.jersey.client.proxy.WebResourceFactory.invoke(WebResourceFactory.java:379)
at jdk.proxy2/jdk.proxy2.$Proxy27.updateUserPassword(Unknown Source)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:569)
at com.mirth.connect.client.core.Client$2.invoke(Client.java:273)
at jdk.proxy2/jdk.proxy2.$Proxy27.updateUserPassword(Unknown Source)
at com.mirth.connect.client.core.Client.updateUserPassword(Client.java:450)
at com.mirth.connect.client.ui.Frame.checkOrUpdateUserPassword(Frame.java:1917)
at com.mirth.connect.client.ui.Frame.updateCurrentUser(Frame.java:1858)
at com.mirth.connect.client.ui.FirstLoginDialog.finishButtonActionPerformed(FirstLoginDialog.java:270)
at com.mirth.connect.client.ui.FirstLoginDialog.access$100(FirstLoginDialog.java:35)
at com.mirth.connect.client.ui.FirstLoginDialog$2.actionPerformed(FirstLoginDialog.java:120)
at java.desktop@17.0.14/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1972)
at java.desktop@17.0.14/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2313)
at java.desktop@17.0.14/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
at java.desktop@17.0.14/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
at java.desktop@17.0.14/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
at java.desktop@17.0.14/java.awt.Component.processMouseEvent(Component.java:6626)
at java.desktop@17.0.14/javax.swing.JComponent.processMouseEvent(JComponent.java:3389)
at java.desktop@17.0.14/java.awt.Component.processEvent(Component.java:6391)
at java.desktop@17.0.14/java.awt.Container.processEvent(Container.java:2266)
at java.desktop@17.0.14/java.awt.Component.dispatchEventImpl(Component.java:5001)
at java.desktop@17.0.14/java.awt.Container.dispatchEventImpl(Container.java:2324)
at java.desktop@17.0.14/java.awt.Component.dispatchEvent(Component.java:4833)
at java.desktop@17.0.14/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4948)
at java.desktop@17.0.14/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4575)
at java.desktop@17.0.14/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4516)
at java.desktop@17.0.14/java.awt.Container.dispatchEventImpl(Container.java:2310)
at java.desktop@17.0.14/java.awt.Window.dispatchEventImpl(Window.java:2780)
at java.desktop@17.0.14/java.awt.Component.dispatchEvent(Component.java:4833)
at java.desktop@17.0.14/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:775)
at java.desktop@17.0.14/java.awt.EventQueue$4.run(EventQueue.java:720)
at java.desktop@17.0.14/java.awt.EventQueue$4.run(EventQueue.java:714)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97)
at java.desktop@17.0.14/java.awt.EventQueue$5.run(EventQueue.java:747)
at java.desktop@17.0.14/java.awt.EventQueue$5.run(EventQueue.java:745)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.desktop@17.0.14/java.awt.EventQueue.dispatchEvent(EventQueue.java:744)
at java.desktop@17.0.14/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop@17.0.14/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop@17.0.14/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:117)
at java.desktop@17.0.14/java.awt.WaitDispatchSupport$2.run(WaitDispatchSupport.java:191)
at java.desktop@17.0.14/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
at java.desktop@17.0.14/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
at java.desktop@17.0.14/java.awt.EventQueue$4.run(EventQueue.java:720)
at java.desktop@17.0.14/java.awt.EventQueue$4.run(EventQueue.java:714)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.desktop@17.0.14/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
at java.desktop@17.0.14/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop@17.0.14/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop@17.0.14/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop@17.0.14/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop@17.0.14/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop@17.0.14/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Caused by: com.mirth.commons.encryption.EncryptionException: com.mirth.commons.encryption.EncryptionException: java.security.NoSuchAlgorithmException: SHA1PRNG SecureRandom not available
at com.mirth.commons.encryption.Digester.digest(Digester.java:207)
at com.mirth.connect.server.controllers.DefaultUserController.checkOrUpdateUserPassword(DefaultUserController.java:189)
at com.mirth.connect.server.api.servlets.UserServlet.updateUserPassword(UserServlet.java:296)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:569)
at com.mirth.connect.server.api.providers.MirthResourceInvocationHandlerProvider$1.invoke(MirthResourceInvocationHandlerProvider.java:219)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:205)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:471)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:425)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:383)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:336)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:223)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799)
at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1656)
at com.mirth.connect.server.api.providers.StrictTransportSecurityFilter.doFilter(StrictTransportSecurityFilter.java:33)
at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626)
at com.mirth.connect.server.MethodFilter.doFilter(MethodFilter.java:37)
at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626)
at com.mirth.connect.server.api.providers.RequestedWithFilter.doFilter(RequestedWithFilter.java:53)
at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626)
at com.mirth.connect.server.api.providers.ClickjackingFilter.doFilter(ClickjackingFilter.java:45)
at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626)
at com.mirth.connect.server.api.providers.ApiOriginFilter.doFilter(ApiOriginFilter.java:71)
at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:552)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1440)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:505)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1355)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:59)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.server.Server.handle(Server.java:516)
at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:487)
at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:732)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:479)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.onFillable(SslConnection.java:555)
at org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:410)
at org.eclipse.jetty.io.ssl.SslConnection$2.succeeded(SslConnection.java:164)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131)
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:409)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034)
at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: com.mirth.commons.encryption.EncryptionException: java.security.NoSuchAlgorithmException: SHA1PRNG SecureRandom not available
at com.mirth.commons.encryption.Digester.initialize(Digester.java:181)
at com.mirth.commons.encryption.Digester.digest(Digester.java:195)
... 78 more
Caused by: java.security.NoSuchAlgorithmException: SHA1PRNG SecureRandom not available
at java.base/sun.security.jca.GetInstance.getInstance(GetInstance.java:159)
at java.base/java.security.SecureRandom.getInstance(SecureRandom.java:387)
at com.mirth.commons.encryption.Digester.initialize(Digester.java:179)
... 79 more}
Vulnerability Location
Use of SHA1PRNG can be found in the mirth source itself.
./server/src/com/mirth/commons/encryption/PBEEncryptor.java:83: saltGenerator = SecureRandom.getInstance("SHA1PRNG");
./server/src/com/mirth/commons/encryption/Digester.java:179: saltGenerator = SecureRandom.getInstance("SHA1PRNG");
Environment (please complete the following information if it is applicable to the issue)
- OS: RHEL 9.7
- Java Distribution/Version: openjdk 17.0.18 2026-01-20 LTS
- Connect Version: 4.6.0
Suggested remediation
Switch to a password hash algo that is FIPS-compliant.
We are able to fix this issue and submit a PR. But if there is already a fix in the works we would be happy to use it!
As of now we are looking into using SecureRandom.getInstanceStrong()
More info on that here:
https://stackoverflow.com/questions/27622625/securerandom-with-nativeprng-vs-sha1prng/27638413#27638413
Describe the security issue
SHA1PRNG, the random number generator algorithim, used when setting user passwords does not work on FIPS-compliant systems.
Vulnerability Location
Use of SHA1PRNG can be found in the mirth source itself.
./server/src/com/mirth/commons/encryption/PBEEncryptor.java:83: saltGenerator = SecureRandom.getInstance("SHA1PRNG");
./server/src/com/mirth/commons/encryption/Digester.java:179: saltGenerator = SecureRandom.getInstance("SHA1PRNG");
Environment (please complete the following information if it is applicable to the issue)
Suggested remediation
Switch to a password hash algo that is FIPS-compliant.
We are able to fix this issue and submit a PR. But if there is already a fix in the works we would be happy to use it!
As of now we are looking into using
SecureRandom.getInstanceStrong()More info on that here:
https://stackoverflow.com/questions/27622625/securerandom-with-nativeprng-vs-sha1prng/27638413#27638413