我可以避免使用 JSSE 在命令行上输入密钥存储密码吗?

发布于 2024-10-21 06:21:03 字数 633 浏览 7 评论 0原文

我们正在使用 Maven 2,并拥有一个通过 SSL 客户端身份验证保护的 Maven 存储库管理器。为了使 Maven 能够访问存储库,必须将以下系统属性传递给 Java:

javax.net.ssl.trustStore=trust.jks
javax.net.ssl.trustStorePassword=
javax.net.ssl.keyStore=keystore.p12
javax.net.ssl.keyStoreType=pkcs12
javax.net.ssl.keyStorePassword=

请参阅此 mini -指南了解更多详细信息。

为了在 Maven 中设置这些系统属性,我必须使用 MAVEN_OPTS 环境变量(或直接在命令行上传递它们)。无论哪种方式,当 Maven 实际执行时,所有这些属性都对系统上的其他用户可见(通过 ps),包括我的密钥存储密码。

有没有办法设置这些属性,以便密码不会在命令行上暴露?

We are using Maven 2 and have a maven repository manager secured with SSL client authentication. In order for Maven to access the repository the following system properties must be passed to Java:

javax.net.ssl.trustStore=trust.jks
javax.net.ssl.trustStorePassword=<trustPass>
javax.net.ssl.keyStore=keystore.p12
javax.net.ssl.keyStoreType=pkcs12
javax.net.ssl.keyStorePassword=<keyStorePass>

See this mini-guide for more details.

In order to set these system properties in Maven, I have to use the MAVEN_OPTS environment variable (or pass them directly on the command-line). Either way, when Maven actually executes, all of these properties become visible to other users on the system (via ps), including my key store password.

Is there a way to set these properties so that the password doesn't get exposed on the command-line?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

﹏半生如梦愿梦如真 2024-10-28 06:21:03

OSX

我在 OSX 上提出的解决方案是以下 .mavenrc。它使用 python 脚本访问钥匙串中的密码,以打开客户端证书,然后生成随机密码和具有该随机密码的临时证书。

将其放入 ~/.mavenrc 并将您的客户端证书添加到 OSX 钥匙串中。确保将 MAVEN_CLIENT_CERT 设置为您的客户端证书的位置。

~/.mavenrc

export MAVEN_CLIENT_CERT=<PATH.TO.CLIENT.CERTIFICATE>

# Retrieve secret from keychain
export SECRET=$(python <<END
from subprocess import Popen, PIPE
import re, sys, os

passlabel = os.environ.get("MAVEN_CLIENT_CERT", None)

p = Popen(['security', 'find-generic-password', '-l',passlabel,'-g'], stdout=PIPE, stderr=PIPE, stdin=PIPE)

sys.stdout.write(re.compile('password:\\s"(.*)"').match(p.stderr.read()).group(1))
sys.exit(0)
END)

TMPDIR=/tmp
TMPTMPL=mvn-$(id -u)-XXXXXXXXXX
PASSPHRASE=$(openssl rand -base64 32)
export PASSPHRASE TMPDIR

pemfile=$(mktemp $TMPDIR/$TMPTMPL)
openssl pkcs12 -in $MAVEN_CLIENT_CERT -passin env:SECRET -out $pemfile -passout env:PASSPHRASE
p12file=$(mktemp $TMPDIR/$TMPTMPL)
openssl pkcs12 -export -in $pemfile -out $p12file -passin env:PASSPHRASE -passout env:PASSPHRASE

sh -c "while kill -0 $ 2>/dev/null; do sleep 1; done; rm -f $pemfile; rm -f $p12file;" &

MAVEN_OPTS="$MAVEN_OPTS -Djavax.net.ssl.keyStore=$p12file -Djavax.net.ssl.keyStoreType=pkcs12 -Djavax.net.ssl.keyStorePassword=$PASSPHRASE"

Linux

在 Linux 上,以下 .mavenrc 将与 gnome 密钥环一起使用(确保将证书密码添加到您的登录密钥环并设置 id 变量 KEYRING_ID):

~/.mavenrc

MAVEN_CLIENT_CERT=<PATH.TO.CLIENT.CERTIFICATE>

export KEYRING_NAME="login"
export KEYRING_ID=<KEYRING.ID>

# Try to get secret from the gnome keyring 
export SECRET=$(python <<END
import sys, os
# Test for gtk
try:
  import gtk #ensure that the application name is correctly set
  import gnomekeyring as gk
except ImportError:
  gtk = None
if gtk:
  id = os.environ.get("KEYRING_ID", None)
  name = os.environ.get("KEYRING_NAME", None)
  try:
    if id:
      info = gk.item_get_info_sync(name, int(id))
      attr = gk.item_get_attributes_sync(name, int(id))
      sys.stdout.write(str(info.get_secret()))
    else:
      params = {}
      types = {'secret': gk.ITEM_GENERIC_SECRET, 'network': gk.ITEM_NETWORK_PASSWORD, 'note': gk.ITEM_NOTE}
      eparams = os.environ.get("KEYRING_PARAMS", None)
      etype = os.environ.get("KEYRING_ITEMTYPE", None)
      if eparams and etype:
        list = eparams.split(',')
        for i in list:
          if i:
            k, v = i.split('=', 1)
            if v.isdigit():
              params[k] = int(v)
            else:
              params[k] = v
        matches = gk.find_items_sync(types[etype], params)
        # Write 1st out and break out of loop. 
        # TODO: Handle more then one secret.
        for match in matches:
          sys.stdout.write(str(match.secret))
          break
    sys.exit(0)
  except gk.Error:
    pass
sys.exit(1)
END
)

TMPDIR=/dev/shm
TMPTMPL=mvn-$(id -u)-XXXXXXXXXX
PASSPHRASE=$(openssl rand -base64 32)
export PASSPHRASE TMPDIR

pemfile=$(mktemp $TMPDIR/$TMPTMPL)
openssl pkcs12 -in $MAVEN_CLIENT_CERT -passin env:SECRET -out $pemfile -passout env:PASSPHRASE
p12file=$(mktemp $TMPDIR/$TMPTMPL)
openssl pkcs12 -export -in $pemfile -out $p12file -passin env:PASSPHRASE -passout env:PASSPHRASE

sh -c "while kill -0 $ 2>/dev/null; do sleep 1; done; rm -f $pemfile; rm -f $p12file;" &

MAVEN_OPTS="$MAVEN_OPTS -Djavax.net.ssl.keyStore=$p12file -Djavax.net.ssl.keyStoreType=pkcs12 -Djavax.net.ssl.keyStorePassword=$PASSPHRASE"

OSX

The solution I came up with on OSX is the following .mavenrc. It uses a python script to access the password in the keychain in order to open the client certificate and then generates a random passphrase and a temporary certificate with that random password.

Put this in ~/.mavenrc and add your client certificate to the OSX keychain. Make sure and set MAVEN_CLIENT_CERT to the location of your client certificate.

~/.mavenrc

export MAVEN_CLIENT_CERT=<PATH.TO.CLIENT.CERTIFICATE>

# Retrieve secret from keychain
export SECRET=$(python <<END
from subprocess import Popen, PIPE
import re, sys, os

passlabel = os.environ.get("MAVEN_CLIENT_CERT", None)

p = Popen(['security', 'find-generic-password', '-l',passlabel,'-g'], stdout=PIPE, stderr=PIPE, stdin=PIPE)

sys.stdout.write(re.compile('password:\\s"(.*)"').match(p.stderr.read()).group(1))
sys.exit(0)
END)

TMPDIR=/tmp
TMPTMPL=mvn-$(id -u)-XXXXXXXXXX
PASSPHRASE=$(openssl rand -base64 32)
export PASSPHRASE TMPDIR

pemfile=$(mktemp $TMPDIR/$TMPTMPL)
openssl pkcs12 -in $MAVEN_CLIENT_CERT -passin env:SECRET -out $pemfile -passout env:PASSPHRASE
p12file=$(mktemp $TMPDIR/$TMPTMPL)
openssl pkcs12 -export -in $pemfile -out $p12file -passin env:PASSPHRASE -passout env:PASSPHRASE

sh -c "while kill -0 $ 2>/dev/null; do sleep 1; done; rm -f $pemfile; rm -f $p12file;" &

MAVEN_OPTS="$MAVEN_OPTS -Djavax.net.ssl.keyStore=$p12file -Djavax.net.ssl.keyStoreType=pkcs12 -Djavax.net.ssl.keyStorePassword=$PASSPHRASE"

Linux

On Linux, the following .mavenrc will work with gnome keyring (make sure and add the cert password to your login keyring and set the id variable KEYRING_ID):

~/.mavenrc

MAVEN_CLIENT_CERT=<PATH.TO.CLIENT.CERTIFICATE>

export KEYRING_NAME="login"
export KEYRING_ID=<KEYRING.ID>

# Try to get secret from the gnome keyring 
export SECRET=$(python <<END
import sys, os
# Test for gtk
try:
  import gtk #ensure that the application name is correctly set
  import gnomekeyring as gk
except ImportError:
  gtk = None
if gtk:
  id = os.environ.get("KEYRING_ID", None)
  name = os.environ.get("KEYRING_NAME", None)
  try:
    if id:
      info = gk.item_get_info_sync(name, int(id))
      attr = gk.item_get_attributes_sync(name, int(id))
      sys.stdout.write(str(info.get_secret()))
    else:
      params = {}
      types = {'secret': gk.ITEM_GENERIC_SECRET, 'network': gk.ITEM_NETWORK_PASSWORD, 'note': gk.ITEM_NOTE}
      eparams = os.environ.get("KEYRING_PARAMS", None)
      etype = os.environ.get("KEYRING_ITEMTYPE", None)
      if eparams and etype:
        list = eparams.split(',')
        for i in list:
          if i:
            k, v = i.split('=', 1)
            if v.isdigit():
              params[k] = int(v)
            else:
              params[k] = v
        matches = gk.find_items_sync(types[etype], params)
        # Write 1st out and break out of loop. 
        # TODO: Handle more then one secret.
        for match in matches:
          sys.stdout.write(str(match.secret))
          break
    sys.exit(0)
  except gk.Error:
    pass
sys.exit(1)
END
)

TMPDIR=/dev/shm
TMPTMPL=mvn-$(id -u)-XXXXXXXXXX
PASSPHRASE=$(openssl rand -base64 32)
export PASSPHRASE TMPDIR

pemfile=$(mktemp $TMPDIR/$TMPTMPL)
openssl pkcs12 -in $MAVEN_CLIENT_CERT -passin env:SECRET -out $pemfile -passout env:PASSPHRASE
p12file=$(mktemp $TMPDIR/$TMPTMPL)
openssl pkcs12 -export -in $pemfile -out $p12file -passin env:PASSPHRASE -passout env:PASSPHRASE

sh -c "while kill -0 $ 2>/dev/null; do sleep 1; done; rm -f $pemfile; rm -f $p12file;" &

MAVEN_OPTS="$MAVEN_OPTS -Djavax.net.ssl.keyStore=$p12file -Djavax.net.ssl.keyStoreType=pkcs12 -Djavax.net.ssl.keyStorePassword=$PASSPHRASE"
初见 2024-10-28 06:21:03

在 OSX 上,您可以使用钥匙串作为密钥库(据我所知,仍然存在一个错误,因此它仅在只有一个“身份”时才有效,即证书+私钥的一种组合)。

请使用它,使用 -Djavax.net.ssl.keyStore=NONE-Djavax.net.ssl.keyStoreType=KeychainStore-Djavax.net.ssl .keyStorePassword=-

然后,钥匙串将在需要时提示您批准使用私钥。

On OSX, you can use your the keychain as a keystore (as far as I know, there is still a bug, so it only works if there is only one "identity", that is one combination of cert+private key).

Do use it, use -Djavax.net.ssl.keyStore=NONE, -Djavax.net.ssl.keyStoreType=KeychainStore and -Djavax.net.ssl.keyStorePassword=-.

The keychain will then prompt you to approve the use of the private key when it's required.

微凉徒眸意 2024-10-28 06:21:03

您可以在 Maven 设置文件中定义这些属性。它们的访问方式与您在命令行上提供它们时的方式相同。以下是 Maven 设置文件的示例:

<profiles>
    <profile>
        <id>repo-ssl</id>
        <properties>
            <javax.net.ssl.trustStore>trust.jks</javax.net.ssl.trustStore>
            <javax.net.ssl.trustStorePassword>SET_TRUSTSTORE_PASSWORD</javax.net.ssl.trustStorePassword>
            <javax.net.ssl.keyStore>keystore.p12</javax.net.ssl.keyStore>
            <javax.net.ssl.keyStoreType>pkcs12</javax.net.ssl.keyStoreType>
            <javax.net.ssl.keyStorePassword>SET_KEYSTORE_PASSWORD</javax.net.ssl.keyStorePassword>
        </properties>
    </profile>
</profiles>

<activeProfiles>
    <activeProfile>repo-ssl</activeProfile>
</activeProfiles>

虽然我没有做与您尝试相同的事情,但我在处理机密时使用了相同的技术。

You can define these properties in your Maven Settings file. They will be accessible in the same way as when you provide them on the command line. Here is an example for your Maven Settings file:

<profiles>
    <profile>
        <id>repo-ssl</id>
        <properties>
            <javax.net.ssl.trustStore>trust.jks</javax.net.ssl.trustStore>
            <javax.net.ssl.trustStorePassword>SET_TRUSTSTORE_PASSWORD</javax.net.ssl.trustStorePassword>
            <javax.net.ssl.keyStore>keystore.p12</javax.net.ssl.keyStore>
            <javax.net.ssl.keyStoreType>pkcs12</javax.net.ssl.keyStoreType>
            <javax.net.ssl.keyStorePassword>SET_KEYSTORE_PASSWORD</javax.net.ssl.keyStorePassword>
        </properties>
    </profile>
</profiles>

<activeProfiles>
    <activeProfile>repo-ssl</activeProfile>
</activeProfiles>

Although I have not done the same thing you are attempting I have used this same technique when dealing with secrets.

拿命拼未来 2024-10-28 06:21:03

是的,您可以在获取初始 SSLContext 之前在代码中使用 System.setProperty(),或者您可以经历创建自己的 KeyManager 等的痛苦和痛苦,如示例中所述JSEE 参考指南。

Yes, you can either use System.setProperty() in your code, before getting the initial SSLContext, or you can go through the agony and pain of creating your own KeyManager etc etc etc as described with examples in the JSEE Reference Guide.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文