Maven 3の[パスワード暗号化機能を理解しようとしています。この機能は十分に文書化されておらず、混乱していることがわかりました。たとえば、 機能のドキュメント と 機能の作成者によるブログ投稿 は、いくつかの点で互いに矛盾しています。
この質問は maven --encrypt-master-passwordはどのように機能するか よりも幅広いので、 Mavenの暗号化マスターパスワードのパスワードを選択するための適切な方法 ではカバーされていません。
具体的には、ドキュメントに記載されていない以下の質問に回答しようとしています。イタリック体の各質問の下に、これまでに収集できた情報を記載しました。
settings-security.xml
)の~/.m2
に存在するだけでセキュリティを提供しますか?もしそうなら、なぜ「マスターパスワード」の暗号化に煩わしいのでしょうか(なぜランダムな値を使用しないのですか?) 「マスターパスワード」は本当に暗号化機能への単なるエントロピー入力ではないのですか?それをパスワードと呼ぶのは混乱を招きます-暗号化されたサーバーパスワードを復号化する前に、Mavenがこのパスワードを要求するよう求めましたが、そうではありませんでした。私の理解は、はい、これはオペレーティングシステムで保護されたファイルに存在することによってのみセキュリティを提供するということです。 Mavenではマスターパスワードを暗号化できるため、settings-security.xml
ファイルを紛失した場合に再生成できると思います。これは正しいです?
maven --encrypt-master-passwordはどのように機能するかに関するマルセロモラレスの回答GitHubのplexus-cihperプロジェクト へのリンク。それが単なる暗号なのか、それともパスワード機能を提供する実際のMavenプラグインなのかは明確ではありません。
わかりません。
settings-security.xml
ファイルに保存されている場合でも機能します。パスワードの暗号文が異なります。誰かがこれがどのように機能するか説明できますか?わかりません。これは、Mavenが怪しげなことをしている、またはクリアテキストをどこかに保存しているように思えます。
<server />
ファイルのsettings.xml
タグでのみ使用できることを理解しています。これは本当ですか? settings.xml
で定義されたサーバーはどこで使用できますか?私の理解では、<server />
の定義は<repositories />
および<distributionManagement />
では使用できますが、<scm />
では使用できません。誰かがこれを確認できますか?
わからない
テキストの壁でごめんなさい、そして答えてくれてありがとう。
私の答えは、Mavenのソースコードを読んで少し調査することに基づいています。
- 暗号化されたマスターパスワードは、1人のユーザーのみがアクセスできるフォルダー(
settings-security.xml
)の~/.m2
に存在するだけでセキュリティを提供しますか?もしそうなら、なぜ「マスターパスワード」の暗号化に煩わしいのでしょうか(なぜランダムな値を使用しないのですか?) 「マスターパスワード」は本当に暗号化機能への単なるエントロピー入力ではないのですか?それをパスワードと呼ぶのは混乱を招きます-暗号化されたサーバーパスワードを復号化する前に、Mavenがこのパスワードを要求するよう求めましたが、そうではありませんでした。
マスターパスワードは、サーバーパスワードを暗号化/復号化するための暗号化機能への入力です。暗号化された個々のサーバーパスワードを誰かが持っている場合、マスターパスワードも持っていない限り、そのユーザーはそれらを解読できません。つまり、サーバーのパスワードを復号化することなく、mavenのsettings.xmlファイルを他のユーザーと自由に共有できます。これは、マスターパスワードが別のファイルに保存される理由でもあります。
この理論的根拠は 暗号化ガイド でいくらか説明されています
- マスターパスワードとサーバーパスワードは同じ暗号化プロセス/暗号を使用していますか?サーバーのパスワードはマスターパスワードに基づいているため、アルゴリズムには多少の違いがあるはずです。これのソースコードはどこにありますか?
私が知ることができることから、マスターパスワードはサーバーパスワードと同じ暗号を使用して暗号化されています。サーバーパスワードを復号化する場合、マスターパスワード(暗号化されていない形式)が入力になります。マスターパスワードを復号化するとき、魔法の文字列「 "settings.security"」が追加の入力として使用されます。
ソースコード PBECipher および MavenCli.Java を確認できます。
- 同じマスターパスワードまたはサーバーパスワードを複数回暗号化すると、異なるハッシュが得られることを確認しました。 Marcelo MoralesによるHow to maven --encrypt-master-password work によると、これは、「JVM構成固有(通常はSHA1PRNG)64ビットランダムソルト」が暗号化する前のパスワード。 Mavenは、保存されたパスワードをコンパイル時に使用するときに復号化します。これは、塩をどこかに保管する必要があることを意味しませんか?
ソルトを処理する従来のアプローチは、ランダムなソルトが暗号化されたテキストとともに保存されるというものです。 Wikipediaの記事 を参照してください。
上記のリンクされたソースコードに基づくと、ソルトはBase64でデコードされたバイトの最初の8バイトとして、暗号化されたパスワードの直前に格納されているように見えます。
- また、1つの暗号化されたマスターパスワードを使用して暗号化された通常のパスワードは、マスターパスワードが再暗号化され、
settings-security.xml
ファイルに保存されている場合でも機能します。パスワードの暗号文が異なります。誰かがこれがどのように機能するか説明できますか?
これは、暗号化された「暗号文」ではなく、マスターパスワードのdecrypted形式が使用されるためです。したがって、再暗号化してもサーバーのパスワードの暗号化/復号化には影響しません。
最後の2つ(5と6)の質問に対する答えはわかりません。
より詳細な分析を共有できるように、bnd(tools)についてこれを知る必要があります。
「暗号化された」パスワードの構文は次のとおりです。
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は「security.settings」です。これはよく知られている定数なので、マスターパスワードは暗号化されずに隠されます。サーバーパスワードの場合、Xはデコードされたマスターパスワードです。
パケット形式によってストリップが簡単になり、暗号化/復号化の一部になることはないため、結果のパケットが埋め込まれる理由はバイトの無駄のようです。いくつかのランダムな文字をbase64文字列に追加するだけです。
これが役立つ唯一の方法は、再配置機能を使用することです。たとえば、ビルドサーバーのプライベートマウントにsettings-security.xmlをマウントする場合。その後、自由にsettings.xml
公開リポジトリのファイル。ただし、すべてのユーザーとCIビルドサーバーで同じマウントポイントをマウントする必要があるため、これも厄介なソリューションです。
プラグインはすべてのサーバーパスワードをデコードできるため、サーバーに実際のパスワードを使用しないでください。 Nexusはプロキシパスワードを作成できます。
以下は、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にはサンプルプロジェクトもあります。