java 我可以避免使用 JSSE 在命令行上输入密钥库密码吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5252040/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can I avoid putting key store password on command-line with JSSE?
提问by kldavis4
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:
我们正在使用 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>
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-guidefor 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.
为了在 Maven 中设置这些系统属性,我必须使用 MAVEN_OPTS 环境变量(或直接在命令行上传递它们)。无论哪种方式,当 Maven 实际执行时,系统上的其他用户(通过 ps)都可以看到所有这些属性,包括我的密钥库密码。
Is there a way to set these properties so that the password doesn't get exposed on the command-line?
有没有办法设置这些属性,以便密码不会在命令行上暴露?
采纳答案by kldavis4
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.
我在 OSX 上提出的解决方案如下.mavenrc
。它使用 python 脚本访问钥匙串中的密码以打开客户端证书,然后使用该随机密码生成随机密码和临时证书。
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
并将您的客户端证书添加到 OSX 钥匙串。确保并设置MAVEN_CLIENT_CERT
为您的客户端证书的位置。
~/.mavenrc
~/.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
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
):
在 Linux 上,以下 .mavenrc 将与 gnome 密钥环一起使用(确保将证书密码添加到您的登录密钥环并设置 id 变量KEYRING_ID
):
~/.mavenrc
~/.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"
回答by Bruno
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).
在 OSX 上,您可以将钥匙串用作密钥库(据我所知,仍然存在一个错误,因此它仅在只有一个“身份”,即证书 + 私钥的一种组合时才有效)。
Do use it, use -Djavax.net.ssl.keyStore=NONE
, -Djavax.net.ssl.keyStoreType=KeychainStore
and -Djavax.net.ssl.keyStorePassword=-
.
使用它,使用-Djavax.net.ssl.keyStore=NONE
,-Djavax.net.ssl.keyStoreType=KeychainStore
和-Djavax.net.ssl.keyStorePassword=-
。
The keychain will then prompt you to approve the use of the private key when it's required.
然后,钥匙串会在需要时提示您批准使用私钥。
回答by XORshift
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:
您可以在 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>
Although I have not done the same thing you are attempting I have used this same technique when dealing with secrets.
虽然我没有做你正在尝试的同样的事情,但我在处理秘密时使用了同样的技术。
回答by user207421
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.
是的,您可以System.setProperty()
在获得初始 SSLContext 之前在您的代码中使用,或者您可以按照 JSEE 参考指南中的示例所述,经历创建自己的 KeyManager 等的痛苦和痛苦。