7

我们正在使用 Maven 2,并有一个使用 SSL 客户端身份验证保护的 Maven 存储库管理器。为了让 Maven 访问存储库,必须将以下系统属性传递给 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>

有关更多详细信息,请参阅此迷你指南

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

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

4

4 回答 4

4

操作系统

我在 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"
于 2012-05-17T23:52:50.027 回答
3

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.

于 2012-05-18T00:31:10.300 回答
2

您可以在 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>

虽然我没有做你正在尝试的同样的事情,但我在处理秘密时使用了同样的技术。

于 2011-10-08T01:30:44.480 回答
0

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

于 2011-10-08T01:04:31.320 回答