2011-10-13 8 views
19

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

+0

これは:https://www.chemaxon.com/forum/ftopic65.html? – home

+0

問題のジャーはどこから来たのですか?なぜ開発環境にサインインできないのですか? –

+1

明らかに方法があります。 ;-)しかし、開発中にJARに署名するのは避けてください。あなたがJARをコントロールしている人なら、これはあなたの力にあるはずです。 JARを管理している人でなければ、おそらくそれを改ざんするつもりはない(あるいはオリジナルの開発者がそれに署名していないだろう)。 –

答えて

25

私は答えを知っているが、ここで私はどうなるのかですありません。

  1. 解凍問題のjarファイルまたはファイル(jarが単なるzip圧縮されている)
  2. META-INFディレクトリの中をご覧くださいMANIFEST-MFではないもののために。
  3. 削除してください。
  4. MANIFEST-MFを開き、署名関連のように見えるものを削除します。
  5. rejar。
+0

これはあなたのやることとほぼ同じです。 – Paul

+1

パーフェクト返信.. – Sid

+0

それは私がしなければならなかったことであり、私は解凍せずに署名を取り除く方法は決して見つけられませんでした。しかし、この答えがステップ2,3,4に関してより具体的であった場合には、MANIFEST-MF以外のものが必要とされ、署名に関連しないことがあるので、私は望みます。 APPLICATION.JNLPのように! – Jason

0

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

+0

私は同じことをやっています。私は大きなアプリの小さな部分を修正する請負業者として働いており、ビルドサーバーは署名を自動化します。私はテストのために提供されたjarファイルのクラスを開発し、オーバーライドする必要があります。彼らは証明書を保持しています(それは銀行なので)私は彼らのビルドの成果を彼らの条件で処理しなければなりません。 – peterk

+0

jarは私が開発しているもので、デプロイするまで署名する必要はありませんが、時には私の開発環境でproduction jarを使用したり、すでに署名したjarファイルを使用したい場合があります展開する。この場合、すべての瓶を解凍し、署名を取り除き、再圧縮するのは苦痛です。私はそれ以来、私のビルドシステムを改造したので、これはもはや頻繁に起きません。私のビルドシステムでは、署名されていないjarと署名付きjarファイルをビルドディレクトリに保持していますので、私の余暇でそれらを切り替えることができます。 – Jason

1

小さな変更でDwBの答えを正常に確認しました:Is there a quick way to delete a file from a Jar/war without having to extract the jar and recreate it?の状態では、jarツールからの削除はできません。私は独自のビルドスクリプトを少し変更するだけで済むようにしなければなりませんでした。

私は重要な.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 
+0

私はこのソリューションをテストする時間がありませんが、それは良いもののように見えます。 – Jason

+0

jarsignerツールのドキュメントから、 1).SFファイル(シグネチャファイル) 2)使用されているアルゴリズム(例:RSA、.DSAなど)に基づくシグネチャブロックファイル 3)変更まだ作成されていない場合の作成)MANIFEST.MFファイル 要約:最初の2つのファイルを削除し、MANIFEST.MFファイルを削除するか、ファイルを開いてそこにリストされているファイルごとにリストされたハッシュをすべて削除してください) 。 それ以外のファイル(プロパティファイルなど)は削除されます。 参照: https://docs.oracle.com/javase/8/docs/technotes/tools/windows/jarsigner.html – atom88

8

それからMETA-INFディレクトリを削除、jarファイルから署名を削除するには。あなたがこれを行うことができますLinuxのように、jarファイルはzipファイルです:

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

あなたがunsignする多くのjarファイルを持っている場合は、次のコマンドは、現在のディレクトリで、以下のすべてのjarファイルでこれを実行します。

find . -name '*.jar' -exec zip -d '{}' 'META-INF/*.SF' 'META-INF/*.RSA' ';' 
+0

また、 'META-INF/MANIFEST.MF'を編集する必要があると思います?または、そのファイルに署名を残して、jarファイルがまだ署名されていないようにすることはできますか? – Jason

+0

ファイルを削除するだけで問題なく動作するようです。 – martinhans

+0

チェックしていただきありがとうございます、私はup-votedしました。私は自分自身でこれを検証しておらず、すべての場合にうまくいくと懐疑的です。私は懐疑心に気をつけないことを願っています:-)解決策は素晴らしいですし、私の場合にはうまくいけば、私の質問に対するより満足のいく回答になるでしょう。 – Jason

4

私は答えがすでに受け入れられている参照、しかし、私は、これはとにかく便利かもしれないと思う:

私はタスクを自動化する(一部は他の記事から)何かを調理しました。
保証は一切ありませんが、それは私のために働きます:)
署名情報を削除している間にJarファイルをコピーします。
注意:MANIFESTは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")); 
    } 

} 

次のように瓶の束をunsignするANTでの使用:

<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> 
+0

素晴らしいアイデア!私はそれをテストしていないが、私はいくつかの注意を引いて、誰かがこの解決策をテストする時間を持っているかどうかを調べるようにアップボードをしている。これはまさに私が望むだろう。 – Jason

+0

ありがとうございます。私たちはかなり長い間それを使ってきました。きれいに働く – Houtman

0

を使用すると、jarsignerツールを見ればとそれは何をするのですか? 1).SFファイル(署名ファイル) 2)使用されているアルゴリズムに基づく署名ブロックファイル(例:RSA、.DSAなど) 3)マニフェストの修正または作成。MFファイル

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

META-INFディレクトリのEVERYTHINGを削除すると、必要になるかもしれない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ファイルに署名すると、アーカイブ内の各ファイルには、アーカイブのマニフェストにダイジェストエントリが与えられます。ここでは、そのようなエントリがどのように見えるかの例です:

名:テスト/クラス/ ClassOne.class SHA1ダイジェスト:JARファイルが署名された場合TD1GZt8G11dXY2p4olSZPc5Rj64 =

、シグネチャファイルが自動的に生成され、 JARファイルのMETA-INFディレクトリに格納されます。このディレクトリは、アーカイブのマニフェストを含むディレクトリと同じディレクトリです。シグネチャファイルの拡張子は.SFです。 JARファイルが署名されている場合

署名ファイルに加えて、署名ブロックファイル

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

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

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

関連する問題