1

我想使用 jarsigner 对两打 jar 文件进行签名,只提供一次密码。

根据手册页,无法将多个文件提供给 jarsigner,并且在命令行上使用 for-loop 仍然会强制我为每个文件输入密码。

我更喜欢命令行的解决方案,但可以使用 ant/maven 解决方案。
系统是Linux。

如何签署十几个 jar 文件,只提供一次密码?

4

2 回答 2

1

这是 PSCode 的 Ant 构建文件的一个片段——它签署了一系列的 Jars。诀窍在于foreach元素。

<target name="createjars"
  depends="compile"
  description="Jars the compiled classes">
    <mkdir dir="${build}/jar/" />

    <foreach target="jar.package" param="package" inheritall="true">
        <path>
            <dirset dir="${src}/java/org/pscode" includes="**/*" />
        </path>
    </foreach>
</target>

..和..

<target name='jar.package'>
    <script language='javascript'>
        <![CDATA[
            prop = pscode.getProperty('package');
            index1 = prop.lastIndexOf('pscode') + 7;
            index2 = prop.length();
            prop1 = prop;
            path = prop1.substring( index1, index2 );
            path2 = path.replaceAll('\\\\','/');
            pscode.setProperty('path', path2 );

            name = path2.replaceAll('/','.');
            pscode.setProperty('jar.name', name + '.jar' );
        ]]>
    </script>

    <xmlproperty file="${src}/java/org/pscode/${path}/manifest.xml" />
    <!-- echo message='jar.name: ${jar.name} *** ${application.title}' / -->
    <if>
        <not>
            <uptodate targetfile='${build}/dist/lib/${jar.name}' >
                <srcfiles dir= '${build}/share/org/pscode/${path}' includes='*.class'/>
            </uptodate>
        </not>
        <then>
            <jar
                destfile='${build}/dist/lib/${jar.name}'
                index='true'
                update='true'>
                <manifest>
                        <attribute name="Implementation-Title" value="${application.title}" />
                        <attribute name="Implementation-Vendor" value="${vendor}" />
                        <attribute name="Implementation-Vendor-Id" value="org.pscode" />
                        <attribute name='Implementation-Version' value='${now}' />
                </manifest>
                <fileset dir='${build}/share'>
                    <include name='org/pscode/${path}/*.class' />
                </fileset>
                <fileset dir='${src}/java'>
                    <include name='org/pscode/${path}/*.png' />
                    <include name='org/pscode/${path}/*.jpg' />
                    <include name='org/pscode/${path}/*.gif' />
                    <include name='org/pscode/${path}/*.xml' />
                    <include name='org/pscode/${path}/*.html' />
                    <include name='org/pscode/${path}/*.ser' />
                </fileset>
            </jar>
        </then>
    </if>

    <!-- If the Jar is updated, any previous signatures will be invalid, it
    needs to be signed again. We cannot use the issigned condition since
    that merely checks if a Jar is signed, not if the digital signatures are
    valid. -->
    <exec
        executable='${jar.signer}'
        resultproperty='jar.signer.result.property'
        outputproperty='jar.signer.output.property'>
        <arg value='-verify' />
        <arg value='${build}/dist/lib/${jar.name}' />
    </exec>

    <if>
        <or>
            <not>
                <equals arg1='${jar.signer.result.property}' arg2='0' />
            </not>
            <or>
                <contains
                    string='${jar.signer.output.property}'
                    substring='unsigned'
                    casesensitive='false' />
                <or>
                    <contains
                        string='${jar.signer.output.property}'
                        substring='SecurityException'
                        casesensitive='false' />
                </or>
            </or>
        </or>
        <then>
            <signjar
                jar='${build}/dist/lib/${jar.name}'
                alias='pscode'
                storepass='${sign.password}'
                force='true'
                verbose='${verbose}'
                keystore='${user.home}/${sign.pathfilename}' />
        </then>
    </if>

</target>
于 2012-06-06T09:23:40.667 回答
1

仅作记录:能够使用/命令行选项和or修饰符jarsigner从文件或环境变量中读取密钥库和密钥密码。-keypass-storepass:file:env

因此,可以将每个密码放在一个文件中(在我的示例中:~/.storepassand ~/.keypass)并使用这样的 for 循环使用 key 对当前目录中的所有 jar 进行签名key_alias

for i in ./*.jar; do jarsigner -storepass:file ~/.storepass -keypass:file ~/.keypass "$i" key_alias;done

要让 jarsigner 从环境变量中读取密码,您必须首先创建这些变量:

export storepass="mystorepassword"
export keypass="mykeypassword"

现在,循环看起来像:

for i in ./*.jar; do jarsigner -storepass:env storepass -keypass:env keypass jarfile.jar key_alias;done
于 2016-01-26T10:52:52.863 回答