web-dev-qa-db-ja.com

jarファイルの署名を解除するにはどうすればよいですか?

Java jarファイルの署名を解除する方法はありますか?開発環境で使用しようとしている署名付きjarがいくつかありますが、セキュリティ例外が発生するため、それらのjarの署名を解除します。後で展開する準備ができたら、署名することができます。

26
Jason

答えはわかりませんが、これが私がすることです:

  1. 問題のjarファイルを解凍します(jarは単なるzipです)
  2. META-INFディレクトリで、MANIFEST-MFではないものを探します。
  3. そのものを削除します。
  4. MANIFEST-MFを開き、署名に関連しているように見えたものを削除します。
  5. rejar。
26
DwB

Jarファイルから署名を削除するには、META-INFディレクトリから。 jarファイルはZipファイルなので、Linuxではこれを実行できます。

Zip -d file.jar 'META-INF/*.SF' 'META-INF/*.RSA'

署名を解除するjarファイルが多数ある場合、次のコマンドは、現在のディレクトリ以下のすべてのjarファイルに対してこれを実行します。

find . -name '*.jar' -exec Zip -d '{}' 'META-INF/*.SF' 'META-INF/*.RSA' ';'
14
martinhans

回答はすでに受け入れられているようですが、とにかくこれは便利かもしれません。

タスクを自動化するために(一部他の投稿から)何かを調理しました。
保証は一切ありませんが、私にとっては機能します:)
署名情報を削除しながらJarファイルをコピーします。
マニフェストにはMAINセクションのみが残っています。

使用する javac JarUnsigner.Javaは、.classファイルを作成します
使用する Java -cp <class dir> JarUnsigner <inJar> <outJar>

import Java.io.BufferedReader;
import Java.io.File;
import Java.io.FileOutputStream;
import Java.io.IOException;
import Java.io.InputStream;
import Java.io.InputStreamReader;
import Java.util.Enumeration;
import Java.util.Zip.ZipEntry;
import Java.util.Zip.ZipFile;
import Java.util.Zip.ZipOutputStream;

public class JarUnsigner {

  private static final String MANIFEST = "META-INF/MANIFEST.MF";

  public static void main(String[] args){

    if (args.length!=2){
      System.out.println("Arguments: <infile.jar> <outfile.jar>");
      System.exit(1);
    }
    String infile = args[0];
    String outfile = args[1];
    if ((new File(outfile)).exists()){
      System.out.println("Output file already exists:" + outfile);
      System.exit(1);
    }
    try{
      ZipFile zipFile = new ZipFile(infile);
      final ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(outfile));
      for (Enumeration e = zipFile.entries(); e.hasMoreElements();) {
        ZipEntry entryIn = (ZipEntry) e.nextElement();

        if (! exclude_file( entryIn.getName() ) ) {

          /* copy the entry as-is */
          zos.putNextEntry( new ZipEntry( entryIn.getName() ));
          InputStream is = zipFile.getInputStream(entryIn);
          byte[] buf = new byte[1024];
          int len;
          while ((len = (is.read(buf))) > 0) {
            zos.write(buf, 0, len);
          }
          zos.closeEntry();

        } else {

          if (MANIFEST.equals(entryIn.getName())){
            /* if MANIFEST, adjust the entry */
            zos.putNextEntry(new ZipEntry(MANIFEST));

            // manifest entries until first empty line. i.e. the 'MainAttributes' section
            // (this method is used so to keep the formatting exactly the same)
            InputStream mIS = zipFile.getInputStream(entryIn);
            BufferedReader in = new BufferedReader(new InputStreamReader(mIS));
            String line = in.readLine();
            byte[] mNL = "\n".getBytes("UTF-8");
            while( line != null && !line.trim().isEmpty() ) {
              zos.write( line.getBytes("UTF-8"));
              zos.write( mNL );
              line = in.readLine();
            }
            zos.write( mNL );
            zos.closeEntry();

          }else{
            /* else: Leave out the Signature files */
          }

        }

      }
      zos.close();
      System.out.println("Successfully unsigned " + outfile);

    }catch(IOException ex){
      System.err.println("Error for file: " + infile);
      ex.printStackTrace();
      System.exit(1);
    }
  }

  /**
   * Exclude .SF signature file
   * Exclude .RSA and DSA (signed version of .SF file) 
   * Exclude SIG-  files  (unknown sign types for signed .SF file)
   * Exclude Manifest file
   * @param filename
   * @return 
   */
  public static boolean exclude_file(String filename){
    return filename.equals("META-INF/MANIFEST.MF") ||
           filename.startsWith("META-INF/SIG-") || 
           filename.startsWith("META-INF/") && ( filename.endsWith(".SF") || filename.endsWith(".RSA") || filename.endsWith(".DSA") );
  }

}

次のように、ANTで使用して、jarファイルの束の署名を解除します。

<apply executable="Java" dest="${output-dir}"> 
  <arg value="-cp" />
  <arg value="${dev-dir}" />
  <arg value="JarUnsigner" />
  <srcfile/> 
  <targetfile/>
  <fileset dir="${input-dir}" includes="*.jar"/> 
  <mapper type="glob" from="*.jar" to="*.jar"/> <!-- uses "dest"-->
</apply> 
8
Houtman

私は小さな変更を加えてDwBの回答の検証に成功しました: jarを抽出して再作成せずに、jar/warからファイルを削除する簡単な方法はありますか? 状態、jarツールからの削除だけではありません可能。プロプライエタリなビルドスクリプトに小さな変更を加えるだけでよく、jarファイル全体をrejarしたくありませんでした。

重要な.RSAファイルのサイズをゼロにしただけで、署名解除が可能であることに気付きました。これは、jar uコマンドでのみ実行できます。

cd %JAR_DIR%
jar xvf myapp.jar META-INF/MYAPP.RSA
type nul > META-INF/MYAPP.RSA
jar uvf myapp.jar META-INF/MYAPP.RSA
rmdir /S/Q META-INF
1

Jarがあなたによって開発された場合、それらは信頼でき、おそらく署名する必要はありません。ただし、外部から取得した場合は、使用する前にセキュリティ例外が発生する理由を調査する必要があります。

0
RHT

Jarsignerツールとその機能を確認すると、3つのものが生成されます。1).SFファイル(署名ファイル)2)使用されるアルゴリズムに基づく署名ブロックファイル(.RSA、.DSAなど)3 )MANIFEST.MFファイルの変更または作成

概要:「jarファイルの署名を解除」するには、最初の2つのファイル(.sfおよび.dsa/rsa FILE)を削除するだけです。 MANIFEST.MFファイルを削除するか、ファイルを開いて、各.classにリストされているハッシュとそこにリストされている他のファイルをすべて削除します。

したがって、META-INFディレクトリ内のすべてを削除すると、必要になる可能性のあるjarの他のリソース(プロパティファイルなど)が削除されるリスクがあります。 「署名関連に見える」すべてを削除するこの「ショットガンアプローチ」は有害であり、次の原則に従っていません。1つ目は(.jarに対して)害を与えません。

ここを参照してください: https://docs.Oracle.com/javase/8/docs/technotes/tools/windows/jarsigner.html

https://docs.Oracle.com/javase/tutorial/deployment/jar/intro.html

署名と検証について

"... JARファイルに署名すると、公開鍵は関連する証明書とともにアーカイブ内に配置されるため、署名を検証したい人が簡単に使用できるようになります。..ダイジェストと署名ファイル

JARファイルに署名すると、アーカイブ内の各ファイルには、アーカイブのマニフェスト内のダイジェストエントリが与えられます。このようなエントリの例を次に示します。

名前:test/classes/ClassOne.class SHA1-Digest:TD1GZt8G11dXY2p4olSZPc5Rj64 =

JARファイルに署名すると、署名ファイルが自動的に生成され、JARファイルのMETA-INFディレクトリ(アーカイブのマニフェストと同じディレクトリ)に配置されます。署名ファイルには、拡張子が.SFのファイル名があります。

署名ブロックファイル

署名ファイルに加えて、JARファイルが署名されると、署名ブロックファイルがMETA-INFディレクトリに自動的に配置されます。マニフェストファイルや署名ファイルとは異なり、署名ブロックファイルは人間が読める形式ではありません。

署名ブロックファイルには、検証に不可欠な2つの要素が含まれています。

署名者の秘密鍵で生成されたJARファイルのデジタル署名署名者の公開鍵を含む証明書は、署名されたJARファイルを検証したい人が使用します。署名ブロックファイル名には通常、作成されたことを示す.DSA拡張子が付きます。デフォルトのデジタル署名アルゴリズム。他の標準アルゴリズムに関連付けられたキーが署名に使用される場合、他のファイル名拡張子が可能です。

0
atom88