当前位置: 首页 > 面试题库 >

如何加密JConsole密码文件的密码

宗政元青
2023-03-14
问题内容

我正在使用JConsole访问我的应用程序MBean,并且使用了password.properties文件。但是根据Sun的规范,此文件仅包含明文格式的密码。

com.sun.management.jmxremote.password.file=<someLocation>/password.properties

现在,我想对密码进行加密并将其用于JConsole的JMX用户身份验证(“远程”部分中的“用户名”和“密码”字段)。我可以使用任何预定义的加密逻辑或自己的加密算法。

是否有人知道将这种纯文本密码更改为加密密码,这样JMX Framework也知道加密密码吗?

我当前的密码文件:

guest  guest
admin  admin

使用加密,它应该看起来像:

guest  ENC(RjqpRYbAOwbAfAEDBdHJ7Q4l/GO5IoJidZctNT5oG64=)
admin  ENC(psg3EnDei6fVRuqHeLwOqNTgIWkwQTjI2+u2O7MXXWc=)

问题答案:

您可以使用com.sun.management.jmxremote.login.configmanagement.properties文件中的配置参数(请参阅%JAVA_HOME%/
lib / management / management.properties)来配置要使用的Authenticator和LoginModule。

默认值如下:

JMXPluggableAuthenticator {
    com.sun.jmx.remote.security.FileLoginModule required;
};

读取纯文本密码文件jmxremote.password。由于com.sun.jmx.remote.security.JMXPluggableAuthenticator可以将其重新配置为使用任何LoginModule实现,因此您可以自由选择现有的LoginModule,也可以自由地使用加密的密码文件来实现自己的LoginModule。

要重新实现FileLoginModule,您应该看一下该attemptAuthentication(boolean)方法,该方法实际上执行身份验证,并且您可能将要替换它。实现该javax.security.auth.spi.LoginModule接口并使用给定的CallbackHandler(您将从init()方法中获取该接口)询问用户名和密码。加密/散列收到的密码,并将其与从加密密码文件读取的密码进行比较。伪代码

public class EncryptedFileLoginModule implements LoginModule {

@Override
public void initialize(Subject subject, CallbackHandler callbackHandler,
        Map<String, ?> sharedState, Map<String, ?> options) {
    this.subject = subject;
    this.callbackHandler = callbackHandler;
}

public boolean login() throws LoginException {
    attemptLogin();
    if (username == null || password == null) {
        throw new LoginException("Either no username or no password specified");
    }
    MessageDigest instance = MessageDigest.getInstance("SHA-1");
    byte[] raw = new String(password).getBytes();
    byte[] crypted = instance.digest(raw);
    // TODO: Compare to the one stored locally
    if (!authenticated) throw new LoginException();
    return true;
}

private void attemptLogin() throws LoginException {
    Callback[] callbacks = new Callback[2];
    callbacks[0] = new NameCallback("username");
    callbacks[1] = new PasswordCallback("password", false);
        callbackHandler.handle(callbacks);
        username = ((NameCallback) callbacks[0]).getName();
        user = new JMXPrincipal(username);
        char[] tmpPassword = ((PasswordCallback) callbacks[1]).getPassword();
        password = new char[tmpPassword.length];
        System.arraycopy(tmpPassword, 0, password, 0, tmpPassword.length);
        ((PasswordCallback) callbacks[1]).clearPassword();
}

但是,由于这已经是服务器端,因此如果您不通过SSL强制实施JMX,密码仍然会以纯文本格式传输。因此,可以强制实施SSL或使用另一种传输协议机制来对凭据进行编码,然后再通过有线传输它们。

总而言之,最好依赖JAAS提供的现有身份验证机制。例如,如果您在本地Windows环境中运行,则可以轻松地使用NTLoginModulefor自动登录。但这仅适用于本地计算机。

创建一个文件c:/temp/mysecurity.cfg:

MyLoginModule {
 com.sun.security.auth.module.NTLoginModule REQUIRED  debug=true debugNative=true;
};

接下来,配置jmxremote.access文件以包含您希望授予对JMX服务器访问权限的用户名或角色:

monitorRole readonly
controlRole readwrite ...
mhaller readonly

(我建议启用调试模式,直到它起作用为止。当用户尝试登录时,您将看到所有用户名,域名和组名。)为服务器设置以下JVM参数:

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=8686
-Dcom.sun.management.jmxremote.authenticate=true
-Dcom.sun.management.jmxremote.ssl=true
-Djava.net.preferIPv4Stack=true
-Djava.security.auth.login.config=c:/temp/mysecurity.cfg
-Dcom.sun.management.jmxremote.login.config=MyLoginModule

启动您的应用程序,然后尝试使用JConsole或VisualVM进行连接。

请注意,尽管将不使用JConsole,但您需要指定用户名和密码。任何密码和用户名都可以使用。原因是因为jconsole将尝试使用空的用户名和空密码进行身份验证,这将被明确阻止。当用户未输入用户名和密码时,VisualVM通过使用空字符串作为用户名和密码来做得更好。

还要注意,远程连接时NTLoginModule不起作用,我认为您必须使用更复杂的登录模块,但Sun已经提供了足够的登录模块:

  • com.sun.security.auth.module.Krb5LoginModule: 使用Kerberos协议对用户进行身份验证
  • com.sun.security.auth.module.LdapLoginModule: (Java 6中的新增功能):通过指定技术连接用户来对LDAP服务器执行身份验证
  • com.sun.security.auth.module.JndiLoginModule: 对在JNDI上下文中注册的LDAP服务器执行身份验证
  • com.sun.security.auth.module.KeyStoreLoginModule: 使用Java密钥库对用户进行身份验证。支持PIN或智能卡身份验证。

您将要看看 LdapLoginModule



 类似资料:
  • 问题内容: 我已经以加密格式将用户密码存储在数据库中。但是,现在,当用户想要登录并尝试输入其原始密码时,该代码始终会将输入的(原始)密码与数据库中存储的加密版本进行比较,从而导致登录失败。 请告诉我如何比较输入的(原始)密码和存储在数据库中的加密密码。 问题答案: 几乎可以肯定,您应该对密码进行 哈希处理 ,而不是使用可逆加密。您可能还需要 用盐 来做…在这种情况下,正确的步骤是: 查找最初对密码

  • 在FTPS中,密码在尝试通过internet连接服务器时被加密。这就是我所理解的,如果我的理解有任何遗漏,请更正。我的问题是,当我厌倦了模拟它(FTPs和FTP)时,我只是得到一条消息,说SSL已经建立(以及基于隐式和显式调用的端口更改)。 是否有任何其他方式来确认密码是真正加密的,或者我们可以看到密码时,它的普通FTP。下面是我在服务器端看到的日志 启用FTP时的服务器日志- 状态:TLS/SS

  • cmf_password($pw, $authCode = '') 功能 CMF密码加密方法 参数 $pw: string 要加密的原始密码 $authCode: string 加密字符串 返回 string 加密后的密码 例子 echo cmf_password('666666');

  • 问题内容: 我正在尝试学习如何使用Java进行基于密码的加密。我在网上找到了几个示例,但在Stack Overflow上还没有(到目前为止)。这些示例对我的解释不大,尤其是在算法选择方面。似乎有很多传递字符串来说明要使用什么算法,但是很少有关于字符串来自何处以及含义的文档。而且似乎不同的算法可能需要KeySpec类的不同实现,所以我不确定哪种算法可以使用我正在查看的PBEKeySpec类。此外,所

  • 问题内容: 我需要访问joomla用户表以从外部php脚本[codeignitor]进行登录检查。 joomla这样存储密码 看起来这不是正常的MD5,所以我无法使用。 创建密码的可能方式是什么? 谢谢。 问题答案: Joomla密码是经过MD5哈希处理的,但是在哈希处理之前,已对密码进行了固定处理。它们被存储在数据库中,因为此盐是长度为32个字符的随机字符串。 因此,要创建一个新的密码哈希, 编

  • 我们是ActiveMQ新手,已经阅读了关于加密密码的文档。 本文档介绍如何设置环境变量(即ACTIVEMQ\u ENCRYPTION\u PASSWORD)以保存加密密码,启动ACTIVEMQ,然后取消设置该环境变量。但是,在服务器重启的情况下,这将如何工作呢?我们无法将该加密密码放入任何systemd服务文件。 我们的安全策略不允许加密密码保留在任何配置或设置文件中,特别是因为解密机制也可以通过