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

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

上官凯泽
2023-03-14
问题内容

我们正在使用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)变为可见,包括我的密钥存储密码。

有没有一种方法可以设置这些属性,以使密码不会在命令行中公开?


问题答案:

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密钥环配合使用(确保将cert密码添加到您的登录密钥环中,并设置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"


 类似资料:
  • 问题内容: 我们可以在密钥存储区中加载多个证书和密钥吗? 是否总是需要仅加载对(即证书和密钥一起)? 如果密钥库具有多个证书和密钥,那么当Java SSL尝试建立作为服务器的连接时,将选择哪个证书和密钥? 问题答案: 尽管这取决于KeyStore类型,但是通常,您可以在单个存储中存储多个私钥和证书。 基于Java的服务器使用哪种密钥和证书组合取决于应用程序的实现方式。许多应用程序允许您使用 别名

  • 问题内容: 我使用openssl生成认证密钥。这是我的命令: openssl genrsa -des3 -out enc_key.pem 1024 我导出到cer文件中,然后使用java keytool导入到Java keystore(jks)中。 密钥库听起来不错。我可以从Java应用程序加载密钥库。 问题是客户端连接到服务器(在这种情况下是FTP服务器,而不是Web服务器,而我使用apache

  • 我们试图更好地保护API密钥(想想用来验证客户端到endpoint的令牌)。这将全部在我们的内部网络上,但我们仍然希望确定只有我们的移动客户端可以调用endpoint。 我想我们可以将API键放入Firebase远程配置参数中(在应用程序中内置一个无效的默认值)。但是,远程配置的Firebase文档说: 不要将机密数据存储在远程配置参数键或参数值中。可以解码存储在项目远程配置设置中的任何参数键或值

  • 我试图在我的一个项目中使用Google Maps API,并在指导中设置API凭据,它希望我将应用程序的SHA-1签名证书指纹添加到API中。 在说明中,它说使用下面的命令来获取指纹: 当我尝试使用它时,无论是在Android Studio终端还是在我的应用程序目录中的cmd提示符,我都得到以下错误: 注意,我的应用程序在D:\Projects\Android\AppName中。 我如何获得我的S

  • KeyToolException:无法从存储区“C:\Keystore\Keystore.jks”中读取密钥“app name”密钥:密钥存储区被篡改,或者密码不正确 我最好的解决办法是什么?

  • 问题内容: 我正在创建一个存储密码的应用程序,用户可以检索和查看该密码。密码用于硬件设备,因此无法检查哈希值。 我需要知道的是: 如何在PHP中加密和解密密码? 什么是最安全的密码加密算法? 我在哪里存储私钥? 除了存储私钥之外,要求用户在需要解密密码的任何时间都输入私钥是一个好主意吗?(可以信任此应用程序的用户) 密码可以通过什么方式被盗和解密?我需要注意什么? 问题答案: 就个人而言,我会像其