设置Java系统属性而不将值放在命令行上

| 我有一些Java代码,取决于系统属性
super.secret.password
。运行我的应用程序时,需要设置该属性。该应用程序将由Shell脚本启动,并且密码将以最小的读取权限保存在文件中。 我真的不想写:
java -Dsuper.secret.password=letmein gov.fortknox.MyApp
因为那样的话,任何可以登录到计算机并运行
ps
top
的人都可以看到密码。 因此,有没有一种好的方法可以设置系统属性而不在命令行中公开它们? 我们提出的唯一通用解决方案是编写一个小的C程序,该程序从文件中读取系统属性,然后使用JNI调用API启动JVM。不用说,我们不愿意这样做。 如果没有不使用命令行就可以设置它们的方法,有没有一种方法可以使命令行隐藏起来?我们正在使用Red Hat Enterprise Linux Server 5.5。 就其价值而言,有问题的应用程序实际上是JBoss EAP 4.3.0,我们正在使用系统属性在其XML配置文件中填充替换结构(
${like.this}
)。有特定于JBoss的解决方案-使用SystemPropertiesService(默认情况下,通过deploy目录中的properties-service.xml文件进行配置),或将-P选项传递给run.sh。但是,我对更一般的情况感兴趣,在这种情况下,可以是任何Java程序。
已邀请:
您可以在启动附近的某个地方读取文件,然后调用ѭ5。对于Web应用程序,请使用ѭ6,这样会较早发生,请参见此答案以获取快速示例。 更新:对于JBoss加载其配置文件的用例来说,这可能还不够早。
如果您担心要以明文形式显示ѭ0的值,但是您不担心有人因为使用权限或其他方法解决了该问题而使用正确的密码值来调用程序,那么我认为您可以只需在启动脚本中加密密码,然后使用包装器类对其进行解密即可。
java -Dsuper.secret.password=BbWvOuliHZVHVwsXudsj14d1iXzo655R gov.fortknox.DecryptWrapper
如果凭据是用于数据源的,我还应该指出其他针对JBoss的解决方案:
SecureIdentityLoginModule
基本上完成了上述工作,而
PBEUtils
SecureIdentityLoginModule
一起使用时提供了密钥库解决方案。请参阅EncryptingDataSourcePasswords。 最后,Peter Lawery提出的使用文件的建议也是有效的。
编写了“ cryptomainia”来解决这个确切的问题。它解密main()参数。 https://github.com/birchb1024/cryptomainia
您可以从包含主要方法的类的静态初始化程序中的某个文件中读取它:
    static {
        try {
          FileReader fr = new FileReader(FILE_NAME);
          // read the property
          System.setProperty(property.getName(), property.getValue());
        } catch (final FileNotFoundException ex) {
          logger.log(Level.SEVERE, ex.getMessage(), ex);
        } catch (final IOException ex) {
          logger.log(Level.SEVERE, ex.getMessage(), ex);
        }
    } 
    ...
    public static void main(...){
    ...
    }
您可以使用JAVA_TOOL_OPTIONS环境变量并在那里设置属性。但是它将仍然在您的脚本文件中可见。
如果攻击者可以物理访问您的计算机,那么没有真正的理由他们无法拥有该计算机-可以通过简单的rot13来避免随意的眼光。 如果攻击者具有某些特权(例如,运行顶层),但没有物理访问权限,则可以使用专门的用户帐户(例如,web-server-user)执行该程序,该用户的特权很少,但是具有独占权限。读取对包含密码的文件的访问权限。然后,您使用该用户帐户启动应用程序,然后传入文件路径。 这样做依赖于操作系统中的访问权限限制,这可能比您自己推出的要好得多。

要回复问题请先登录注册