服务响应时间慢:Java SecureRandom 和 /dev/random [重复]

2023-11-26

我正在尝试调试 Tomcat 上部署的应用程序提供的一些缓慢响应。 现在我专注于SecureRandom and /dev/random(已调查并排除了其他一些可能的原因)。 模式如下:

  • 第一次调用正好需要30.0Tomcat 重启后的 xy 秒(即使请求在启动后 4 分钟到达)
  • 后来,有些调用恰好需要15.0pq 秒(我无法建立特定的模式,pq是 TP99 中所用时间的近似时间)

服务调用涉及加密和解密(AES/ECB/PKCS5填充).

SecureRandom 初始化/重新填充是否有可能导致这种情况?

(虽然,catalina.log 中有一条日志说"Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [28,760] milliseconds.")

另外,为了检查是否/dev/random or /dev/urandom正在使用,我使用了测试这个问题。令我惊讶的是,我没有看到他们中任何一个的阅读内容,这与链接问题中发生的方式不同。 这些是最后几行strace log:

3561  lstat("/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre/lib/jsse.jar", {st_mode=S_IFREG|0644, st_size=258525, ...}) = 0
3561  open("/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre/lib/jsse.jar", O_RDONLY) = 6
3561  stat("/dev/random", {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 8), ...}) = 0
3561  stat("/dev/urandom", {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 9), ...}) = 0
3561  open("/dev/random", O_RDONLY)     = 7
3561  open("/dev/urandom", O_RDONLY)    = 8
3561  unlink("/tmp/hsperfdata_xxxx/3560") = 0

那么使用什么来播种 SecureRandom 呢?

fyi, java版本

java version "1.6.0_32"
OpenJDK Runtime Environment (IcedTea6 1.13.4) (rhel-7.1.13.4.el6_5-x86_64)
OpenJDK 64-Bit Server VM (build 23.25-b01, mixed mode)

我无法检查您的 OpenJDK 具体版本,但我可以检查jdk6-b33.

安全随机 uses 种子生成器获取种子字节

public byte[] engineGenerateSeed(int numBytes) {
    byte[] b = new byte[numBytes];
    SeedGenerator.generateSeed(b);
    return b;
}

SeedGenerator 获取seedSource(字符串)来自太阳条目

String egdSource = SunEntries.getSeedSource();

SunEntries尝试从系统属性获取源java.security.egd首先,如果没有找到则尝试获取该属性securerandom.source来自java.security属性文件,如果未找到属性则返回空字符串。

// name of the *System* property, takes precedence over PROP_RNDSOURCE
private final static String PROP_EGD = "java.security.egd";
// name of the *Security* property
private final static String PROP_RNDSOURCE = "securerandom.source";

final static String URL_DEV_RANDOM = "file:/dev/random";
final static String URL_DEV_URANDOM = "file:/dev/urandom";

private static final String seedSource;

static {
    seedSource = AccessController.doPrivileged(
            new PrivilegedAction<String>() {

        public String run() {
            String egdSource = System.getProperty(PROP_EGD, "");
            if (egdSource.length() != 0) {
                return egdSource;
            }
            egdSource = Security.getProperty(PROP_RNDSOURCE);
            if (egdSource == null) {
                return "";
            }
            return egdSource;
        }
    });
}

the SeedGenerator检查此值以初始化实例

// Static instance is created at link time
private static SeedGenerator instance;

private static final Debug debug = Debug.getInstance("provider");

final static String URL_DEV_RANDOM = SunEntries.URL_DEV_RANDOM;
final static String URL_DEV_URANDOM = SunEntries.URL_DEV_URANDOM;

// Static initializer to hook in selected or best performing generator
static {
    String egdSource = SunEntries.getSeedSource();

    // Try the URL specifying the source
    // e.g. file:/dev/random
    //
    // The URL file:/dev/random or file:/dev/urandom is used to indicate
    // the SeedGenerator using OS support, if available.
    // On Windows, the causes MS CryptoAPI to be used.
    // On Solaris and Linux, this is the identical to using
    // URLSeedGenerator to read from /dev/random

    if (egdSource.equals(URL_DEV_RANDOM) || egdSource.equals(URL_DEV_URANDOM)) {
        try {
            instance = new NativeSeedGenerator();
            if (debug != null) {
                debug.println("Using operating system seed generator");
            }
        } catch (IOException e) {
            if (debug != null) {
                debug.println("Failed to use operating system seed "
                              + "generator: " + e.toString());
            }
        }
    } else if (egdSource.length() != 0) {
        try {
            instance = new URLSeedGenerator(egdSource);
            if (debug != null) {
                debug.println("Using URL seed generator reading from "
                              + egdSource);
            }
        } catch (IOException e) {
            if (debug != null)
                debug.println("Failed to create seed generator with "
                              + egdSource + ": " + e.toString());
        }
    }

    // Fall back to ThreadedSeedGenerator
    if (instance == null) {
        if (debug != null) {
            debug.println("Using default threaded seed generator");
        }
        instance = new ThreadedSeedGenerator();
    }
}

如果来源是

final static String URL_DEV_RANDOM = "file:/dev/random";

or

final static String URL_DEV_URANDOM = "file:/dev/urandom"

使用NativeSeedGenerator,在 Windows 上尝试使用本机CryptoAPI在 Linux 上,该类只是扩展了SeedGenerator.URLSeedGenerator

package sun.security.provider;

import java.io.IOException;

/**
 * Native seed generator for Unix systems. Inherit everything from
 * URLSeedGenerator.
 *
 */
class NativeSeedGenerator extends SeedGenerator.URLSeedGenerator {

    NativeSeedGenerator() throws IOException {
        super();
    }

}

并调用加载的超类构造函数/dev/random默认情况下

URLSeedGenerator() throws IOException {
    this(SeedGenerator.URL_DEV_RANDOM);
}

所以,OpenJDK 使用/dev/random默认情况下,直到您不在系统属性中设置其他值java.security.egd或在房产内securerandom.source安全属性文件。

如果您想使用查看读取结果strace您可以更改命令行并添加trace=open,read表达

sudo strace -o a.strace -f -e trace=open,read java class

你可以看到类似这样的东西(我用 Oracle JDK 6 做了测试)

13225 open("/dev/random", O_RDONLY)     = 8
13225 read(8, "@", 1)                   = 1
13225 read(3, "PK\3\4\n\0\0\0\0\0RyzB\36\320\267\325u\4\0\0u\4\0\0 \0\0\0", 30) = 30
....
....

如果您在启动过程中遇到延迟,为了加快启动速度,Tomcat Wiki 部分建议使用非阻塞熵源,例如 /dev/urandom

更多信息:https://wiki.apache.org/tomcat/HowTo/FasterStartUp#Entropy_Source

希望这可以帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

服务响应时间慢:Java SecureRandom 和 /dev/random [重复] 的相关文章

  • 任务“:app:dexDebug”执行失败

    我目前正在处理我的项目 我决定将我的 Android Studio 更新到新版本 但在我导入项目后 它显示如下错误 Information Gradle tasks app assembleDebug app preBuild UP TO
  • 有没有好的方法来解析用户代理字符串?

    我有一个Java接收模块User Agent来自最终用户浏览器的字符串的行为需要略有不同 具体取决于浏览器类型 浏览器版本甚至操作系统 例如 FireFox 7 0 Win7 Safari 3 2 iOS9 我明白了User Agent由于
  • Java 泛型/类型调度问题

    考虑以下程序 import java util List import java util ArrayList public class TypeTest public static class TypeTestA extends Type
  • 方法断点可能会大大减慢调试速度

    每当向方法声明行添加断点 在 Intellij IDEA 或 Android Studio 中 时 都会出现一个弹出窗口 方法断点可能会大大减慢调试速度 为什么会这样戏剧性地减慢调试速度 是我的问题吗 将断点放在函数的第一行有什么不同 Th
  • JavaFX - setVisible 隐藏元素但不重新排列相邻节点

    在 JavaFX 中 如果我有一个场景有 2VBox元素和每个VBox有多个Label in it 如果我设置顶部VBox to 无形的 为什么底部VBox 不向上移动顶部的场景VBox was The VBox is 无形的但我希望其他物
  • Java 变量的作用域

    我不明白为什么这段代码的输出是10 package uno public class A int x 10 A int x 12 new B public static void main String args int x 11 new
  • Java替换特定字符

    这是我在这个网站上的第一个问题 所以我会尽量不要成为一个十足的菜鸟 我目前正在用java 创建刽子手游戏 所以我问你的问题是我们是否被赋予了 幽灵 这个词 并将 Ghost 替换为 hiddenWord ghost length for i
  • cucumber-junit-platform-engine 中的功能文件发现

    In cucumber junit我使用的库 CucumberOptions定义功能文件位置 package com mycompany cucumber import cucumber api CucumberOptions import
  • 使用 Guava 联合两个 ImmutableEnumSets

    我想联合两个ImmutableEnumSets来自番石榴 这是我的尝试 public final class OurColors public enum Colors RED GREEN BLUE YELLOW PINK BLACK pub
  • 尝试在没有 GatewayIntent 的情况下访问消息内容

    我希望每当我写一条打招呼的消息时 机器人都会在控制台中响应一条消息 但它只是给我一个错误 JDA MainWS ReadThread WARN JDA Attempting to access message content without
  • 不兼容的类型:在 java netbeans 中对象无法转换为 String

    我试图在我的项目中使用对象数组 但出现错误 incompatible types Object cannot be converted to String 在这一行 ST1 new String emt1 emt2 emt3 emt4 现在
  • 我必须做什么才能使通过 HTTPS 提供的图像等内容缓存在客户端?

    我使用 Tomcat 作为服务器 使用 Internet Explorer 6 作为浏览器 我们应用程序中的网页大约有 75 张图像 我们正在使用 SSL 加载所有内容似乎非常慢 如何配置 Tomcat 以便 IE 缓存图像 如果您通过 h
  • 如何为 Jackson 编写一个包罗万象的(反)序列化器

    当您提前知道类型时 编写自定义序列化器非常容易 例如 MyType一个人可以写一个MyTypeSerializer extends StdSerializer
  • 阻止 OSX 变音符号为所有用户禁用 Java 中的 KeyBindings?

    注 我知道这个问题 https stackoverflow com questions 40335285 java keybinds stop working after holding down a key用户必须输入终端命令才能解决此问
  • 来自客户端的超时 Web 服务调用

    我正在使用 RestEasy 客户端调用网络服务 一项要求是 如果调用运行时间超过 5 秒 则中止 超时调用 我如何使用 RestEasy 客户端实现这一目标 我只看到服务器端超时 即如果在一定时间内未完成请求 Rest Easy 网络服务
  • 从java中的字符串数组中删除空值

    java中如何从字符串数组中删除空值 String firstArray test1 test2 test4 我需要像这样没有 null 空 值的 firstArray String firstArray test1 test2 test4
  • 如何移动图像(动画)?

    我正在尝试在 x 轴上移动船 还没有键盘 我如何将运动 动画与boat png而不是任何其他图像 public class Mama extends Applet implements Runnable int width height i
  • struts 教程或示例

    我正在尝试在 Struts 中制作一个登录页面 这个想法是验证用户是否存在等 然后如果有错误 则返回到登录页面 错误显示为红色 典型的登录或任何表单页面验证 我想知道是否有人知道 Struts 中的错误管理教程 我正在专门寻找有关的教程 或
  • 重写Object类的finalize()方法有什么用?

    据我所知 在java中如果我们想手动调用垃圾收集器 我们可以执行System gc 1 我们在重写的finalize 方法中做了哪些操作 2 如果我们想手动调用JVM垃圾收集器 是否需要重写finalize 方法 我们在重写的 Finali
  • Java中有类似分支/跳转表的东西吗?

    Java有类似分支表或跳转表的东西吗 分支表或跳转表是 根据维基百科 http en wikipedia org wiki Branch table 用于描述使用分支指令表将程序控制 分支 转移到程序的另一部分 或可能已动态加载的不同程序

随机推荐

  • 何时在休眠中使用延迟加载/预加载?

    我相信使用 Hibernate 加载对象只有两种方法 一种是延迟加载 一种是预先加载 延迟加载有其自身的优点 它不是加载大量对象 而是仅在需要时才加载 我还了解到 如果您想强制加载一个对象的所有子对象 您可以简单地调用parent getC
  • php 将十进制转换为十六进制

    我正在使用内置 OpenSSL 库从数字证书中提取序列号 但是 我无法将此数字精确转换为十六进制 提取的数字最初是十进制的 但我需要它是十六进制的 我试图转换的数字是 114483222461061018757513232564608398
  • 将SqlDataReader写入立即窗口c#

    我正在尝试调试引发错误的 SQL 响应 将 varchar 值 0 01 转换为数据类型位时转换失败 这没有多大意义 因为对象没有任何书籍 Code using var connection connectionProvider GetDb
  • 如何提前ServiceStack中的会话超时

    ServiceStack 中的身份验证 存储库和缓存提供程序提供了一种简单的方法来将登录会话添加到 Web 应用程序 几乎不需要任何额外的代码 我发现可以配置身份验证提供程序的会话超时 例如 new CredentialsAuthProvi
  • 如何更改 JBoss 7 java Web 服务中的肥皂地址

    如何更改网络服务中的肥皂地址 我正在开发 JBoss 7 1 1 我有这个网络服务类 WebService public class Card WebMethod public CardResponseDTO insertCard WebP
  • 文件获取内容不起作用?

    我正在使用cakephp 我正在尝试使用 file get contents 从 facebook 获取数据 我收到警告 警告 2 file get contents function file get contents URL 服务器中禁
  • 存储每日页面浏览量以及总浏览量的最有效方法

    关于在数据库中存储文章或视频的页面浏览量进行了很多讨论 但我似乎找不到任何有关存储每日页面浏览量的信息 例如 DeviantArt 在一个小图表中向您显示过去 15 天左右的时间以及每个人获得的页面浏览量 以及个人资料的总页面浏览量 您可以
  • 对列表中的元素求和[重复]

    这个问题在这里已经有答案了 这是我的代码 我需要对列表中未定义数量的元素求和 这个怎么做 l raw input l l split l pop 0 我的输入 3 5 4 9输入后我通过删除第一个元素l pop 0 After split
  • 重新排序sql server中的身份主键

    是的 我非常清楚后果 但我只是想重新排序它们 从1开始到结束 如何使用单个查询对键重新排序 它是聚集主键索引 重新排序就像 First record Id 1 second record Id 2 主键是 Int 删除PK约束 删除身份列
  • 错误:任务“:app:processDebugResources”执行失败。 > 在索引 4 处

    在最新 SDK 的修订版 2 更新后 我在构建项目时遇到问题 抱歉 我不记得版本号 我之前成功运行了代码 我不认为我的项目中有任何错误 我经常收到错误消息 因为 IDE 发生内部错误 与此有关 请帮忙谢谢 下面给出了所需的代码 应用程序 b
  • LLVM out of source pass build:不支持可加载模块(在 Linux 上)

    几周前 我在 debian wheezy 上从 trunk 编译并安装了 LLVM 配置和制作 现在尝试从源代码中编译llvm mutate 传递 AFAICC llvm mutate 遵循 cmake超出源通道构建说明 当尝试构建 llv
  • 防止按下后退按钮后重新提交表单

    我在这里的处境有点微妙 在我的组织中 我们设计库存管理系统 它是一个基于 JSP 页面和处理它们的 servlet 的 Web 应用程序 我被要求解决一个特定问题 我们有一个带有 HTML 表单的 JSP 页面 其中包含库存详细信息 当用户
  • 如何使用buildozer和最新的kivy构建kivy应用程序?

    使用 buildozer 我已经成功构建并运行了一个 Android 应用程序 Buildozer 使用 kivy stable 1 7 如何使用最新的 kivy 1 8 构建 kivy 应用程序 我注意到在https github com
  • Android Espresso 多重索引失败

    我们在应用程序中使用 multidex 很长一段时间 但最近最新更新后 它在 android API 如果我为缺少的类定义 multidexKeepProguard 例如 java lang NoClassDefFoundError rx
  • 使用 CSS 为透明文本添加阴影

    有没有办法添加一个阴影透明文本以便文本后面的背景保持可见 也许有某种方法可以使用文本本身作为掩码 或者文本混合模式 具有合理的跨浏览器支持 我天真的尝试 span background image url http i imgur com
  • VS Code 的文档/智能感知弹出窗口在鼠标悬停时消失

    将鼠标悬停在变量上后 我在滚动弹出框时遇到问题 它就这样消失了 我希望能够滚动浏览它 我在 Windows 10 x64 上使用带有 Python 扩展的 Visual Studio Code 1 41 1 Set editor hover
  • C# 是否支持返回类型的类型推断?

    这只是一个好奇心 是否有一个基本的事情可以阻止这样的事情 或者纠正我 如果已经有某种方法 public TTo Convert
  • 如何并行使用 Swift async/await

    考虑下面的代码 class UserProfile private var img UIImage didSet update ui private var bio String didSet update ui private func
  • 如何检查多维数组的任何子数组中的特定键是否存在特定值?

    我需要在多维数组中搜索任何索引子数组中的特定值 换句话说 我需要检查多维数组的单个列中的值 如果该值存在于多维数组中的任何位置 我想返回true否则false my array array 0 gt array name gt john i
  • 服务响应时间慢:Java SecureRandom 和 /dev/random [重复]

    这个问题在这里已经有答案了 我正在尝试调试 Tomcat 上部署的应用程序提供的一些缓慢响应 现在我专注于SecureRandom and dev random 已调查并排除了其他一些可能的原因 模式如下 第一次调用正好需要30 0Tomc