20190531 maven | password encryption

20190531 maven | password encryption

reference:https://maven.apache.org/guides/mini/guide-encryption.html


  1. Introduction
  2. How to create a master password
  3. How to encrypt server passwords
  4. How to keep the master password on removable drive
  5. Tips

    Introduction

    Maven 2.1.0+ now supports server password encryption. The main use case, addressed by this solution is:
  • multiple users share the same build machine (server, CI box)
  • some users have the privilege to deploy Maven artifacts to repositories, some don’t.
    • this applies to any server operations, requiring authorization, not only deployment
  • settings.xml is shared between users

The implemented solution adds the following capabilities:

  • authorized users have an additional settings-security.xml file in their ${user.home}/.m2 folder
    • this file either contains encrypted master password, used to encrypt other passwords
    • or it can contain a relocation - reference to another file, possibly on removable storage
    • this password is created first via CLI for now
  • server entries in the settings.xml have passwords and/or keystore passphrases encrypted
    • for now - this is done via CLI after master password has been created and stored in appropriate location

How to create a master password

Use the following command line:

1
mvn --encrypt-master-password <password>

Note: Since Maven 3.2.1 the password argument should no longer be used (see Tips below for more information). Maven will prompt for the password. Earlier versions of Maven will not prompt for a password, so it must be typed on the command-line in plaintext.

This command will produce an encrypted version of the password, something like

1
{jSMOWnoPFgsHVpMvz5VrIt5kRbzGpI8u+9EF1iFQyJQ=}

Store this password in the ${user.home}/.m2/settings-security.xml; it should look like

1
2
3
<settingsSecurity>
<master>{jSMOWnoPFgsHVpMvz5VrIt5kRbzGpI8u+9EF1iFQyJQ=}</master>
</settingsSecurity>

When this is done, you can start encrypting existing server passwords.

How to encrypt server passwords

You will have to use the following command line:

1
mvn --encrypt-password <password>

Note:Just like --encrypt-master-password the password argument should no longer be used since Maven 3.2.1 (see Tips below for more information.).

This command will produce an encrypted version of it, something like

1
{COQLCE6DU6GtcS5P=}

Cut-n-paste it into your settings.xml file in the server section. This will look like:

1
2
3
4
5
6
7
8
9
10
11
12
13
<settings>
...
<servers>
...
<server>
<id>my.server</id>
<username>foo</username>
<password>{COQLCE6DU6GtcS5P=}</password>
</server>
...
</servers>
...
</settings>

Please note that password can contain any information outside of the curly brackets, so that the following will still work:

1
2
3
4
5
6
7
8
9
10
11
12
13
<settings>
...
<servers>
...
<server>
<id>my.server</id>
<username>foo</username>
<password>Oleg reset this password on 2009-03-11, expires on 2009-04-11 {COQLCE6DU6GtcS5P=}</password>
</server>
...
</servers>
...
</settings>

Then you can use, say, deploy plugin, to write to this server:

1
2
3
mvn deploy:deploy-file -Durl=https://maven.corp.com/repo \
-DrepositoryId=my.server \
-Dfile=your-artifact-1.0.jar \

How to keep the master password on removable drive

Create the master password exactly as described above, and store it on a removable drive, for instance on OSX, my USB drive mounts as /Volumes/mySecureUsb, so I store

1
2
3
<settingsSecurity>
<master>{jSMOWnoPFgsHVpMvz5VrIt5kRbzGpI8u+9EF1iFQyJQ=}</master>
</settingsSecurity>

in the file /Volumes/mySecureUsb/secure/settings-security.xml

And then I create ${user.home}/.m2/settings-security.xml with the following content:

1
2
3
<settingsSecurity>
<relocation>/Volumes/mySecureUsb/secure/settings-security.xml</relocation>
</settingsSecurity>

This assures that encryption will only work when the usb drive is mounted by OS. This addresses a use case where only certain people are authorized to deploy and are issued these devices.

Tips

Escaping curly-brace literals in your password (Since: Maven 2.2.0)

At times, you might find that your password (or the encrypted form of it) may actually contain ‘{‘ or ‘}’ as a literal value. If you added such a password as-is to your settings.xml file, you would find that Maven does strange things with it. Specifically, Maven will treat all the characters preceding the ‘{‘ literal, and all the characters after the ‘}’ literal, as comments. Obviously, this is not the behavior you want in such a situation. What you really need is a way of escaping the curly-brace literals in your password.

Starting in Maven 2.2.0, you can do just this, with the widely used ‘\‘ escape character. If your password looks like this:

1
jSMOWnoPFgsHVpMvz5VrIt5kRbzGpI8u+{EF1iFQyJQ=

Then, the value you would add to your settings.xml would look like this:

1
{jSMOWnoPFgsHVpMvz5VrIt5kRbzGpI8u+\{EF1iFQyJQ=}

Password Security

Editing settings.xml and running the above commands can still leave your password stored locally in plaintext. You may want to check the following locations:

  • Shell history (e.g. by running history). You may want to clear your history after encrypting the above passwords
  • Editor caches (e.g. ~/.viminfo)

Also note that the encrypted passwords can be decrypted by someone that has the master password and settings security file. Keep this file secure (or stored separately) if you expect the possibility that the settings.xml file may be retrieved.

Password Escaping on different platforms

On some platforms it might be neccessary to quote your password based on the content of your password in particular having special characters like %, !, $ etc. in there. For example on Windows you have to be carefull about things like the following:

The following example will not work on Windows:

1
mvn --encrypt-master-password a!$%^b

whereas the following will work on Windows:

1
mvn --encrypt-master-password "a!$%^b"

If you are on a linux/unix platform you should use single quotes for the above master password otherwise you will be astonished that the usage of the master-password will not work (caused by the dollar sign and furthermore the exclamation mark).

Prompting for Password

In Maven before version 3.2.1 you have to give the password on command line as argument which means you might need to escape your password. In addition usually the shell stores the full history of commands you have entered, therefore anyone with access to your computer could restore the password from the shell`s history.

Starting with Maven 3.2.1 the password is an optional argument which means if you omit the password you will be prompted for it which prevents all the issues mentioned above.

Therefore we strongly recommend to use Maven 3.2.1 and above to prevent problems with escaping special characters and of course security issues related to bash history or environment issues in relationship with the password.


  1. 导言(introduction)
  2. 如何创建主密码
  3. 如何加密服务密码
  4. 如何在可移动设备(on removable driver)上保存主密码
  5. 小贴士

导言(introduction)

Maven 2.1.0+ 开始支持服务密码加密。主要用例,解决方案(addressed by solution)是:

  • 所有用户共享相同(same)的构建机器(server,CI box)
  • 一些用户拥有部署 maven 制品(artifacts)到仓库的特权(privilege)。而一些人不能

    • 这适用于(this applies to)任何需要授权的服务器操作,而不仅仅是部署。
    • setting.xml 在用户之间分享

实现的(implemented)解决方案添加了以下功能(capablities):

  • 认证的用户拥有额外的(additional)setting-security.xml 文件在他们的 ${user.home}/.m2 目录

    • 这个文件要么包含(either contains)加密的主密码,用于加密其他密码
    • 或者它可以包含一个迁移(relocaton)- 引用到另一个文件,也许在可移动存储设备上
    • 这个密码先通过(first via) CLI 创建
  • setting.xml 中的服务条目加密了密码 或 密钥仓库密码

    • 现在,主密码被创建并存储到了合适(appropriate)的位置,这是通过 CLI 完成的。

如何创建主密码

使用以下命令

1
mvn --encrypt-master-password <password>
1
注意:从 maven 3.2.1 开始这个密码参数不再(should no longer)使用(查看以下的提示获得更多信息)。maven 将提示(prompt)输入密码。早期(Earlier)版本的 maven 不会提示输入密码,所以必须在命令行输入明文密码。

这个命令将会产生一个密码加密之后的版本,比如下面这样:

1
{jSMOWnoPFgsHVpMvz5VrIt5kRbzGpI8u+9EF1iFQyJQ=}

${user.home}/.m2/settings-security.xml 中存储该密码,像下面这样:

译注:如果没有 settings-security.xml 文件自己创建即可。把内容复制进去。

1
2
3
<settingsSecurity>
<master>{jSMOWnoPFgsHVpMvz5VrIt5kRbzGpI8u+9EF1iFQyJQ=}</master>
</settingsSecurity>

当上述步骤完成之后,你可以开始加密服务器密码了。

如何加密服务密码

你必须使用以下命令:

1
mvn --encrypt-password <password>
1
提示:就像 mvn --encrypt-master-password  一样。这个密码参数从 maven 3.2.1 开始不再使用(见文档)

这个命令会产生一个密码加密后的版本,如:

1
{COQLCE6DU6GtcS5P=}

剪切粘贴到您 setting.xml 文件的服务节点,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
<settings>
...
<servers>
...
<server>
<id>my.server</id>
<username>foo</username>
<password>{COQLCE6DU6GtcS5P=}</password>
</server>
...
</servers>
...
</settings>

请注意:密码可以在花括号外(outside of the curly brackets)包含任意信息。所以以下仍然可以工作:

1
2
3
4
5
6
7
8
9
10
11
12
13
<settings>
...
<servers>
...
<server>
<id>my.server</id>
<username>foo</username>
<password>Oleg reset this password on 2009-03-11, expires on 2009-04-11 {COQLCE6DU6GtcS5P=}</password>
</server>
...
</servers>
...
</settings>

然后,您可以使用,比如说,部署插件。要写入此服务器,请执行以下操作:

1
2
3
mvn deploy:deploy-file -Durl=https://maven.corp.com/repo \
-DrepositoryId=my.server \
-Dfile=your-artifact-1.0.jar \

如何在可移动设备上保存主密码

和上文所述(described above)的一样(exactly as)创建主密码,然后存储到可移动设备中,以 OSX 为例,我的 USB 驱动挂载在 /Volumes/mySecureUsb,所以我存储(以下内容):

1
2
3
<settingsSecurity>
<master>{jSMOWnoPFgsHVpMvz5VrIt5kRbzGpI8u+9EF1iFQyJQ=}</master>
</settingsSecurity>

/Volumes/mySecureUsb/secure/settings-security.xml

然后我创建 ${user.home}/.m2/settings-security.xml ,内容如下:

1
2
3
<settingsSecurity>
<relocation>/Volumes/mySecureUsb/secure/settings-security.xml</relocation>
</settingsSecurity>

这保证了只有当 usb 驱动挂载到了操作系统上(OS)上,加密才能工作。这解决了(this addresses a)一个用例,其中只有特定(certain)的人被授权部署和发布(issued)这些设备。

小提示

在您的密码中转义(escaping)花括号(curly-brace)文本(literals)

有时(as time),你可能发现你的密码(或以此加密的)可能确实包含 {} 作为文字值。

译注:maven 加密的密码最外层都有花括号包围,通常我们加密后的密码都是:{jSMOWnoPFgsHVpMvz5VrIt5kRbzGpI8u+EF1iFQyJQ==} 的形式,密码是 jSMOWnoPFgsHVpMvz5VrIt5kRbzGpI8u+EF1iFQyJQ==。
\
但可能不排除有这样的密码,他们密码中间就包含了花括号:jSMOWnoPFgsHVpMvz5VrIt5kRbzGpI8u+{EF1iFQyJQ=,外面再被一个大括号包围,就成了这样:{jSMOWnoPFgsHVpMvz5VrIt5kRbzGpI8u+{EF1iFQyJQ=}

如果你将这样(such a)的密码原样(as-is)的放在你的 settings.xml 中,你会发现 maven 对此做了一些奇怪(strange)的事情。具体的说(Specifically),maven 会处理(treat) { 字面符之前(preceding)所有的文本(Literals),和处理 } 字面符之后的所有字符。作为评论,很明显的(Obviusly),这种情况(sush a siluation)下,这不是您想要的行为(behavior)。你真正需要的是一种转义(escaping)你密码中的花括号的方法。

从 maven 2.2.0 起,你可以这样做,与广泛使用的(widely used)的 \ 转义字符(escape character)。如果你的密码看起来是这样的:

1
jSMOWnoPFgsHVpMvz5VrIt5kRbzGpI8u+{EF1iFQyJQ=

那么,你可以像这样添加值到你的 settings.xml 中:

1
{jSMOWnoPFgsHVpMvz5VrIt5kRbzGpI8u+\{EF1iFQyJQ=}

密码安全

编辑 settings.xml 并运行以上命令依然可以以明文(plaintext)的形式保存(leave)你的密码到本地,你可能需要检查以下位置:

  • shell 历史(例如:运行 history)。你可能想要在加密(encrying)上述密码(above password)之后清除你的历史记录
  • 编辑器缓存。(例如:~/.viminfo

同样注意(note),加密后的密码可以被拥有主密码和设置安全文件的某些人(someone)解密(decrypted by 被解密)。保持这个文件安全(或分别存储),如果你希望可以(expect polibility 期待可能性)检索(retried) settings.xml 文件的话。

不同平台的密码转义符

在一些平台上,你可能(neccessary)需要基于(base on)你的密码内容添加引号(quote),特别是(in particular)含有特殊字符的比如:%,!,$。例如在 window 上你需要小心比如像以下这种:

以下案例在 Windows 上将不起作用:

1
mvn --encrypt-master-password a!$%^b

然而(whereas),以下内容适用于 Windows:

1
mvn --encrypt-master-password "a!$%^b"

如果你在Linux/Unix平台上,你应该使用上面的主密码的单引号。否则你会惊讶的(astonished)发现使用主密码将不起作用(由美元符号(dollar sign)和感叹号(exclamation mark)引起)。

密码输入提示

在 maven 3.2.1 之前你必须在命令行参数上给定密码,这意味着你可能需要转义(escape)你的密码。此外(in addition),通常 shell 会存储你在命令行输入的完整历史。所以(therefore)任何人访问你电脑的人都可以通过 shell 的历史恢复(restore)你的密码。

从 Maven 3.2.1 开始,密码是一个可选参数,这意味着如果省略(omit)密码,系统将提示(prompted)您输入密码,这将阻止(prevents)上述(above)提过(mentioned)的所有问题(issues)。

译注:使用 mvn –encrypt-master-password 不带密码参数,会要求输入密码。这个输入是不可见的,命令行没有记录的。

因此,我们强烈建议(srongly recommend)使用 Maven 3.2.1 及更高版本来防止(prevent)转义特殊字符的问题,当然(of course)还有与bash历史相关的安全问题或与密码相关的环境问题。

# maven

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×