Java 如何取消jar的签名?
有没有取消java jar文件签名的方法?我有一些已签名的JAR,我正试图在我的开发环境中使用,但我遇到了安全异常,因此我想取消这些JAR的签名,我可以在以后准备部署时对它们进行签名。我不知道答案,但我会这样做:Java 如何取消jar的签名?,java,jar,jar-signing,Java,Jar,Jar Signing,有没有取消java jar文件签名的方法?我有一些已签名的JAR,我正试图在我的开发环境中使用,但我遇到了安全异常,因此我想取消这些JAR的签名,我可以在以后准备部署时对它们进行签名。我不知道答案,但我会这样做: 解压缩一个或多个有问题的jar文件(jar只是拉链) 在META-INF目录中查找不是MANIFEST-MF的内容 删除那些东西 打开MANIFEST-MF并删除看起来与签名相关的内容 雷加 如果JAR是由您开发的,那么它们是可以信任的,您可能不需要签署它们。然而,如果您是从外部获得的
如果JAR是由您开发的,那么它们是可以信任的,您可能不需要签署它们。然而,如果您是从外部获得的,那么在使用它们之前,您应该调查为什么会出现安全异常。我成功地验证了DwB的答案,只做了一点小修改:按照状态,仅从jar工具中删除是不可能的。我只需要对专有构建脚本做一些小的更改,我不想重新构建整个jar 当我只将重要的.RSA文件设置为零大小时,我意识到unsign是可能的。这只能通过
jaru
命令来实现:
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
要从jar文件中删除签名,请从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' ';'
我看到一个答案已经被接受,但我认为这可能是有用的: 我编造了一些东西(部分来自其他帖子)来自动化这项任务。
没有任何担保,但它对我有效:)
在删除签名信息的同时复制Jar文件。
注意,清单只剩下主要部分 使用
javacjarunsier.java
创建.class文件使用
java-cp JarUnsigner
导入java.io.BufferedReader;
导入java.io.File;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.io.InputStream;
导入java.io.InputStreamReader;
导入java.util.Enumeration;
导入java.util.zip.ZipEntry;
导入java.util.zip.ZipFile;
导入java.util.zip.ZipoutStream;
公共类Jarunsier{
私有静态最终字符串MANIFEST=“META-INF/MANIFEST.MF”;
公共静态void main(字符串[]args){
如果(参数长度!=2){
System.out.println(“参数:”);
系统出口(1);
}
字符串infle=args[0];
字符串输出文件=args[1];
如果((新文件(outfile)).exists()){
System.out.println(“输出文件已存在:“+outfile”);
系统出口(1);
}
试一试{
ZipFile ZipFile=新ZipFile(填充);
最终ZipOutputStream zos=新的zipoutpstream(新文件输出流(输出文件));
对于(枚举e=zipFile.entries();e.hasMoreElements();){
ZipEntry entryIn=(ZipEntry)e.nextElement();
如果(!exclude_文件(entryIn.getName())){
/*按原样复制条目*/
新的ZipEntry(entryIn.getName());
InputStream=zipFile.getInputStream(entryIn);
字节[]buf=新字节[1024];
内伦;
而((len=(is.read(buf)))>0){
写(buf,0,len);
}
zos.closeEntry();
}否则{
if(MANIFEST.equals(entryIn.getName())){
/*如果是清单,则调整条目*/
zos.putNextEntry(新ZipEntry(舱单));
//在第一个空行(即“MainAttributes”部分)之前显示条目
//(此方法用于保持格式完全相同)
InputStream mIS=zipFile.getInputStream(entryIn);
BufferedReader in=新的BufferedReader(新的InputStreamReader(mIS));
String line=in.readLine();
字节[]mNL=“\n”。获取字节(“UTF-8”);
while(line!=null&&!line.trim().isEmpty()){
写入(line.getBytes(“UTF-8”);
zos.write(mNL);
line=in.readLine();
}
zos.write(mNL);
zos.closeEntry();
}否则{
/*否则:删除签名文件*/
}
}
}
zos.close();
System.out.println(“成功取消签名”+输出文件);
}捕获(IOEX异常){
System.err.println(“文件错误:+infle”);
例如printStackTrace();
系统出口(1);
}
}
/**
*排除.SF签名文件
*排除.RSA和DSA(签名版本的.SF文件)
*排除SIG文件(signed.SF文件的未知符号类型)
*排除清单文件
*@param文件名
*@返回
*/
公共静态布尔排除_文件(字符串文件名){
返回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的签名,如下所示:
如果您查看jarsigner工具及其功能,它会生成3种功能:
1) .SF文件(签名文件)
2) 基于所用算法的签名块文件(例如RSA、DSA等)
3) 修改或创建MANIFEST.MF文件
总结:
要“取消jar签名”,只需删除前2个文件(.sf和.dsa/rsa文件)。
要么删除MANIFEST.MF文件,要么打开它并删除每个.class和其中列出的其他文件的所有哈希值)
因此,如果删除META-INF目录中的所有内容,则可能会删除jar中可能需要的其他资源(即属性文件等)。这种删除所有“看起来与签名相关”的内容的“散弹枪方法”是有害的,并且不遵循以下原则:1不伤害(对你的.jar)
请看这里:
Tmpdir=tmp.$$
mkdir -p "$Tmpdir"
cd "$Tmpdir"
for i in <jarlocation>/*.jar; do \
printf 'Doing %s\n' "$i"
unzip "$i" 'META-INF/*'
sed -i '/^[[:space:]]*$/,$d' META-INF/MANIFEST.MF
zip -r "$i" META-INF/MANIFEST.MF
test -f META-INF/<signer>.SF && zip -d "$i" 'META-INF/<signer>.*'
rm -rf META-INF
done
cd ..
rm -rf "$Tmpdir"
printf 'Unsigning finished\n'