我试图了解Maven 3的[密码加密功能。我发现这个功能记录不清,令人困惑。例如,feature documentation和a blog post by the author of the feature在几个方面相互矛盾。
此问题比How does maven --encrypt-master-password work更广泛,Maven encrypt-master-password good practice for choosing password未涵盖。
具体来说,我正在尝试回答文档未涵盖的以下问题。我已经在斜体字下面的每个问题下面提供了我能够收集的信息。
settings-security.xml
)的文件夹中~/.m2
中存在,从而提供安全性?如果是这样,为什么还要加密主密码' (为什么不使用一些随机值)?不是主密码'真的只是加密函数的熵输入?将其称为密码令人困惑 - 我希望Maven在解密任何加密的服务器密码之前提示我输入此密码,但事实并非如此。 我的理解是,这只是通过受操作系统保护的文件中存在来提供安全性。我相信Maven允许您加密主密码,这样如果您丢失settings-security.xml
文件,您可以重新生成它。这是对的吗?
Marcelo Morales' answer on How does maven --encrypt-master-password work指向plexus-cihper project on GitHub的链接。目前还不清楚这只是密码,还是提供密码功能的实际Maven插件。
我不知道。
settings-security.xml
文件中,即使加密的主密码密文是现在不同了。有人能解释一下这是如何起作用的吗?我不知道。在我看来,Maven正在做一些可疑的事情或在某处存储明文。
<server />
文件中的settings.xml
标记一起使用。这是真的? settings.xml
中定义的服务器可以在哪里使用? 我的理解是<server />
定义可以在<repositories />
和<distributionManagement />
中使用,但不能在<scm />
中使用。有人可以验证吗?
我不知道
对不起文字墙,感谢您的回答。
答案 0 :(得分:11)
我的回答是基于阅读Maven源代码并进行一些研究。
settings-security.xml
中只存在于一个只有一个用户可以访问的文件夹(~/.m2
)中才能提供安全性?如果是这样,为什么还要加密'主密码'(为什么不使用一些随机值)呢? “主密码”不仅仅是加密函数的熵输入吗?将其称为密码令人困惑 - 我希望Maven在解密任何加密的服务器密码之前提示我输入此密码,但事实并非如此。主密码是加密函数的输入,用于加密/解密服务器密码。如果某人拥有您的个人加密服务器密码,除非他们也拥有您的主密码,否则他们将无法对其进行解密。这意味着您可以与其他人自由共享您的maven settings.xml文件,而无需他们解密您的服务器密码。这也是主密码保存在单独文件中的原因。
这个基本原理在encryption guide
中有所解释据我所知,主密码使用与服务器密码相同的密码加密。解密服务器密码时,主密码(加密形式)是输入;解密主密码时,魔术字符串'“settings.security”'用作附加输入。
您可以看到源代码PBECipher和MavenCli.java。
处理盐的传统方法是随机盐与加密文本一起存储。请参阅Marcelo Morales' answer on How does maven --encrypt-master-password work。
根据上面链接的源代码,salt似乎存储为Base64解码字节的前8个字节,就在加密密码之前。
settings-security.xml
文件中,即使加密的主密码密文是现在不同了。有人能解释一下这是如何起作用的吗?这是因为使用了主密码的解密形式,而不是加密的“密文”。因此,重新加密它不会影响服务器密码加密/解密。
我不知道你最后两(5和6)个问题的答案。
答案 1 :(得分:2)
我需要知道这对于bnd(工具),所以我可以分享一些更深入的分析。
加密&#39;密码的语法为:
output ::= '{' base64(packet) '}'
packet ::= salt[8] padlen[1] encrypted[?] padding[padlen]
salt ::= <random>
padlen ::= <length of padding >
padding ::= <random to make packet length a multiple of 16>
使用的密码是AES/CBC/PKCS5Padding
。秘密密钥和初始化向量计算如下:
sha = sha256( X + salt[8] )
key = sha[0..16]
iv = sha[16..32]
对于主密码,X是&#34; security.settings&#34;。由于这是一个众所周知的常量,因此主密码不会加密,而只会被模糊。对于服务器密码,X是解码的主密码。
为什么生成的数据包被填充似乎是浪费字节,因为数据包格式使剥离变得微不足道,它们永远不会成为加密/解密的一部分。他们只是在base64字符串中添加了一些随机字符。
唯一有用的方法是使用重定位工具。例如,如果将settings-security.xml挂载到构建服务器上的专用挂载上。然后,您可以在公共存储库中自由共享settings.xml
文件。但是,这也是一个很糟糕的解决方案,因为您需要为所有用户和CI构建服务器安装相同的挂载点。
请注意,任何插件都可以解码所有服务器密码,因此永远不要使用服务器的真实密码。 Nexus可以创建代理密码。
答案 2 :(得分:1)
以下示例代码显示如何解密来自
的maven主密码 ~/.m2/security-settings.xml
以及来自
的服务器密码 ~/.m2/settings.xml
MavenPasswordDecryptor.java
import org.sonatype.plexus.components.cipher.DefaultPlexusCipher;
public class MavenPasswordDecryptor {
public static void main(String[] args) throws Exception {
if (args.length < 1 || args.length > 2 ) {
System.out.println("Usage: java -jar maven-password-decryptor.jar <encrypted-password>");
System.out.println("Usage: java -jar maven-password-decryptor.jar <encrypted-password> <master-password>");
return;
}
DefaultPlexusCipher cipher = new DefaultPlexusCipher();
String encryptedPassword = args[0];
String passPhrase = (args.length == 2 && args[1] != null && !args[1].isEmpty()) ? args[1] : "settings.security";
String result = cipher.decryptDecorated(encryptedPassword, passPhrase);
System.out.println(result);
}
}
GitHub上还有一个示例项目: