使用EV代码签名创建Maven JNLP

时间:2017-04-24 18:07:03

标签: java maven code-signing java-web-start maven-webstart-plugin

我使用Maven和 webstart-maven-plugin 生成JNLP文件并签署项目的jar文件。我们只需更新代码签名证书,自2017年2月起,提供硬件代币而非软件代币。

根据GlobalSign支持页面,使用硬件令牌签名罐子的正确方法如下(参见article):

jarsigner -keystore NONE -storetype PKCS11 -tsa http://timestamp.globalsign.com/scripts/timestamp.dll -providerClass sun.security.pkcs11.SunPKCS11 -providerArg eToken.cfg test.jar "le-d0e453de-66db-414a-8fa8-0a07cfad66b5"

我按照该文章中描述的所有步骤进行操作,现在我尝试调整我的pom.xml以应用EV代码签名证书。

最初我使用了密钥库(片段,下面的完整pom):

<!-- SIGNING -->
<sign>
    <keystore>${project.basedir}/src/main/jnlp/my.keystore</keystore>
    <keypass>...</keypass>
    <storepass>...</storepass>
    <alias>...</alias>
    <verify>true</verify>
</sign>

现在我正在尝试更新它以使EV代码签名正常工作(以下片段,完整的pom):

<!-- SIGNING -->
<sign>
    <keystore>NONE</keystore>
    <storetype>PKCS11</storetype>
    <storepass>...</storepass>
    <tsa>http://timestamp.globalsign.com/scripts/timestamp.dll</tsa>
    <providerClass>sun.security.pkcs11.SunPKCS11</providerClass>
    <providerArg>${project.basedir}/src/main/resources/token/eToken.config</providerArg>
    <alias>le-d0e453de-66db-414a-8fa8-0a07cfad66b5</alias> <!-- I took the alias from the article as an example -->
    <verify>true</verify>
</sign>

但是,除非我遗漏了某些内容,否则似乎不支持tsaproviderClassproviderArg。我没有找到很多关于webstart-maven-plugin的信息,或者它没有更新,这是一种耻辱:(

在创建JNLP时是否有其他/更好的方式来签名罐子?任何帮助将不胜感激!

pom.xml代码签名(使用密钥库)

    <profile>
        <id>jnlp</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>webstart-maven-plugin</artifactId>
                    <version>1.0-beta-6</version>
                    <dependencies>
                        <dependency>
                            <groupId>org.codehaus.mojo</groupId>
                            <artifactId>webstart-pack200-impl</artifactId>
                            <version>1.0-beta-6</version>
                        </dependency>
                        <dependency>
                            <groupId>org.codehaus.mojo</groupId>
                            <artifactId>keytool-api-1.7</artifactId>
                            <version>1.5</version>
                        </dependency>
                    </dependencies>
                    <executions>
                        <execution>
                            <phase>package</phase>
                            <goals>
                                <goal>jnlp</goal>
                            </goals>
                        </execution>
                    </executions>
                    <configuration>
                        <!-- The path where the libraries are stored within the jnlp structure. not required. by default the libraries are within the working directory -->
                        <libPath>lib</libPath>
                        <!-- JNLP generation -->
                        <jnlp>
                            <mainClass>myApp.ui.MainApp</mainClass>
                        </jnlp>

                        <!-- SIGNING -->
                        <sign>
                            <keystore>${project.basedir}/src/main/jnlp/my.keystore</keystore>
                            <keypass>...</keypass>
                            <storepass>...</storepass>
                            <alias>...</alias>
                            <verify>true</verify>
                        </sign>
                        <verbose>true</verbose>
                        <updateManifestEntries>
                            <Application-Name>MyApp</Application-Name>
                            <Permissions>all-permissions</Permissions>
                            <Codebase>...</Codebase>
                            <Application-Library-Allowable-Codebase>...</Application-Library-Allowable-Codebase>
                            <Caller-Allowable-Codebase>...</Caller-Allowable-Codebase>
                        </updateManifestEntries>

                        <!-- BUILDING PROCESS -->
                        <pack200>
                            <enabled>false</enabled>
                        </pack200>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-assembly-plugin</artifactId>
                    <version>2.6</version>
                    <configuration>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                    </configuration>
                    <executions>
                        <execution>
                            <id>assemble-all</id>
                            <phase>package</phase>
                            <goals>
                                <goal>single</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </profile>

pom.xml EV代码签名(使用SafeNet令牌)

    <profile>
        <id>jnlp</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>webstart-maven-plugin</artifactId>
                    <version>1.0-beta-7</version>
                    <dependencies>
                        <dependency>
                            <groupId>org.codehaus.mojo</groupId>
                            <artifactId>webstart-pack200-impl</artifactId>
                            <version>1.0-beta-6</version>
                        </dependency>
                        <dependency>
                            <groupId>org.codehaus.mojo</groupId>
                            <artifactId>keytool-api-1.7</artifactId>
                            <version>1.5</version>
                        </dependency>
                    </dependencies>
                    <executions>
                        <execution>
                            <phase>package</phase>
                            <goals>
                                <goal>jnlp</goal>
                            </goals>
                        </execution>
                    </executions>
                    <configuration>
                        <!-- The path where the libraries are stored within the jnlp structure. not required. by default the libraries are within the working directory -->
                        <libPath>lib</libPath>
                        <!-- JNLP generation -->
                        <jnlp>
                            <mainClass>myApp.ui.MainApp</mainClass>
                        </jnlp>

                        <!-- SIGNING -->
                        <sign>
                            <keystore>NONE</keystore>
                            <storetype>PKCS11</storetype>
                            <storepass>...</storepass>
                            <tsa>http://timestamp.globalsign.com/scripts/timestamp.dll</tsa>
                            <providerClass>sun.security.pkcs11.SunPKCS11</providerClass>
                            <providerArg>${project.basedir}/src/main/resources/token/eToken.config</providerArg>
                            <alias>le-d0e453de-66db-414a-8fa8-0a07cfad66b5</alias> <!-- i took the alias from the article as an example -->
                            <verify>true</verify>
                        </sign>
                        <verbose>true</verbose>
                        <updateManifestEntries>
                            <Application-Name>MyApp</Application-Name>
                            <Permissions>all-permissions</Permissions>
                            <Codebase>...</Codebase>
                            <Application-Library-Allowable-Codebase>...</Application-Library-Allowable-Codebase>
                            <Caller-Allowable-Codebase>...</Caller-Allowable-Codebase>
                        </updateManifestEntries>

                        <!-- BUILDING PROCESS -->
                        <pack200>
                            <enabled>false</enabled>
                        </pack200>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-assembly-plugin</artifactId>
                    <version>2.6</version>
                    <configuration>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                    </configuration>
                    <executions>
                        <execution>
                            <id>assemble-all</id>
                            <phase>package</phase>
                            <goals>
                                <goal>single</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </profile>

3 个答案:

答案 0 :(得分:1)

这些天我面临同样的问题。我成功地使用了“解决方法”

解决方法1(一个胖罐):

  • maven-shade-plugin(这是创建具有依赖关系的“胖罐子”的简单方法然后 只签这个罐子)
  • maven-jarsigner-plugin(从令牌签署带阴影的jar)
  • webstart-maven-plugin(仅用于jnlp目的)

这是我的pom:

<dependencies>

    ...

</dependencies>

<build>
    <plugins>

        ...

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.0.0</version>
            <executions>
                <execution>
                    <id>shade</id>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <transformers>
                            <transformer
                                implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                <manifestEntries>
                                    <Permissions>all-permissions</Permissions>
                                </manifestEntries>
                            </transformer>
                        </transformers>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jarsigner-plugin</artifactId>
            <version>1.4</version>
            <executions>
                <execution>
                    <id>sign</id>
                    <phase>package</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <keystore>NONE</keystore>
                <storepass>******</storepass>
                <storetype>PKCS11</storetype>
                <tsa>http://rxxxxx.globalsign.com/advanced</tsa>
                <providerClass>sun.security.pkcs11.SunPKCS11</providerClass>
                <providerArg>${project.basedir}/src/main/eToken.cfg</providerArg>
                <alias>xxxxxxxxxxxxx</alias>
                <archive>${project.build.directory}/${project.build.FinalName}.${project.packaging}</archive>
                <arguments>
                    <argument>-J-Dhttp.proxyHost=my.proxy.com</argument>
                    <argument>-J-Dhttp.proxyPort=8080</argument>
                </arguments>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.codehaus.mojo.webstart</groupId>
            <artifactId>webstart-maven-plugin</artifactId>
            <version>1.0-beta-7</version>
            <executions>
                <execution>
                    <id>build-jnlp</id>
                    <phase>package</phase>
                    <goals>
                        <goal>jnlp</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <makeArchive>false</makeArchive>
                <jnlp>
                    <inputTemplateResourcePath>${project.basedir}/src/main/jnlp</inputTemplateResourcePath>
                    <inputTemplate>template.vm</inputTemplate>
                    <mainClass>test</mainClass>
                </jnlp>
            </configuration>
        </plugin>
    </plugins>

</build>

和template.vm:

<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0+" codebase="http://www.mycompany.com/poc" href="launch.jnlp">
    <information>
        <title>xxxx</title>
        <vendor>$project.Organization.Name</vendor>
        <homepage href="http://www.mycompany.com" />
        <description>$project.Description</description>
        <offline-allowed />
    </information>
    <security>
        <all-permissions />
    </security>
    <resources>
        <j2se version="1.7+" />
        $dependencies
    </resources>
    <application-desc main-class="$mainClass" />
</jnlp>

解决方法2(几个罐子):

  • maven-jar-plugin(设置主jar清单中的所有权限)
  • webstart-maven-plugin(仅用于jnlp目的)
  • maven-jarsigner-plugin(从令牌中签名/ jnlp中的所有jar)

这是我的pom:

<dependencies>

    ...

</dependencies>

<build>
    <plugins>

        ...
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <executions>
                <execution>
                    <id>update-manifest-permissions-entry</id>
                    <phase>prepare-package</phase>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <archive>
                    <addMavenDescriptor>false</addMavenDescriptor>
                    <manifestEntries>
                        <Permissions>all-permissions</Permissions>
                    </manifestEntries>
                </archive>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>webstart-maven-plugin</artifactId>
            <version>1.0-beta-7</version>
            <executions>
                <execution>
                    <id>build-jnlp</id>
                    <phase>package</phase>
                    <goals>
                        <goal>jnlp</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <makeArchive>false</makeArchive>
                <jnlp>
                    <inputTemplateResourcePath>${project.basedir}/src/main/jnlp</inputTemplateResourcePath>
                    <inputTemplate>template.vm</inputTemplate>
                    <mainClass>test</mainClass>
                </jnlp>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jarsigner-plugin</artifactId>
            <version>1.4</version>
            <executions>
                <execution>
                    <id>sign</id>
                    <phase>install</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <keystore>NONE</keystore>
                <storepass>xxxxx</storepass>
                <storetype>PKCS11</storetype>
                <tsa>http://xxx.globalsign.com/xxx</tsa>
                <providerClass>sun.security.pkcs11.SunPKCS11</providerClass>
                <providerArg>${project.basedir}/src/main/eToken.cfg</providerArg>
                <alias>xxxxxxx</alias>
                <processMainArtifact>false</processMainArtifact>
                <archiveDirectory>${project.build.directory}/jnlp</archiveDirectory>
                <arguments>
                    <argument>-J-Dhttp.proxyHost=myproxy.company.com</argument>
                    <argument>-J-Dhttp.proxyPort=8080</argument>
                </arguments>
            </configuration>
        </plugin>
    </plugins>

</build>

和template.vm:

<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0+" codebase="http://www.mycompany.com/poc" href="launch.jnlp">
    <information>
        <title>xxxx</title>
        <vendor>$project.Organization.Name</vendor>
        <homepage href="http://www.mycompany.com" />
        <description>$project.Description</description>
        <offline-allowed />
    </information>
    <security>
        <all-permissions />
    </security>
    <resources>
        <j2se version="1.7+" />
        $dependencies
    </resources>
    <application-desc main-class="$mainClass" />
</jnlp>

答案 1 :(得分:1)

免责声明:我是javafx-maven-plugin的维护者。

此报告现已公布,有关详细信息,请参阅此链接:https://github.com/javafx-maven-plugin/javafx-maven-plugin/issues/291

正如javafx-maven-plugin上已经提到的,以下是解决方案:

<plugin>
    <groupId>com.zenjava</groupId>
    <artifactId>javafx-maven-plugin</artifactId>
    <version>8.8.4-SNAPSHOT</version>
    <!-- this configuration is share among all executions -->
    <configuration>
        <mainClass>fqdn.to.your.MainClass</mainClass>
        <description>test signing</description>
        <title>launch</title>
        <verbose>true</verbose>
        <j2seVersion>1.8+</j2seVersion>
        <appName>simpleApplicationName</appName>

        <!-- this only sets the field inside jar-file -->
        <allPermissions>true</allPermissions>
    </configuration>
    <executions>
        <execution>
            <!-- required before build-native, creates target/jfx/app -->
            <id>create-jfxjar</id>
            <phase>package</phase>
            <goals>
                <goal>build-jar</goal>
            </goals>
        </execution>
        <execution>
            <!-- creates target/jfx/web -->
            <id>create-jnlp-bundle</id>
            <phase>package</phase>
            <goals>
                <goal>build-native</goal>
            </goals>
            <!-- this configuration is only specific to this execution -->
            <configuration>
                <!-- as we only want to create the JNLP-package, use fixed bundler-ID -->
                <bundler>jnlp<bundler>

                <bundleArguments>
                    <!-- this makes the JNLP-file having permissions being set -->
                    <!-- AND it is the trigger for signing jar-files using jarsigner -->
                    <jnlp.allPermisions>true</jnlp.allPermisions>

                    <!-- the JNLP-bundler is a bit picky about its parametes, it does not use <appName> -->
                    <jnlp.outfile>simpleApplicationName</jnlp.outfile>
                </bundleArguments>

                <!-- this setting is required for the new "jarsigner"-feature -->
                <noBlobSigning>true</noBlobSigning>

                <!-- these are required, please change them for your own requirements -->
                <keyStoreAlias>myalias</keyStoreAlias>
                <keyStorePassword>mypass</keyStorePassword>

                <!-- as this keystore is no file, please disable file-checks -->
                <skipKeyStoreChecking>true</skipKeyStoreChecking>
                <!-- this is new too and required, as PKCS11 does not want some keypass -->
                <skipKeypassWhileSigning>true</skipKeypassWhileSigning>

                <!-- this is used for additional parameters for the jarsigner command -->
                <additionalJarsignerParameters>
                    <additionalJarsignerParameter>-keystore</additionalJarsignerParameter>
                    <additionalJarsignerParameter>NONE</additionalJarsignerParameter>
                    <additionalJarsignerParameter>-storetype</additionalJarsignerParameter>
                    <additionalJarsignerParameter>PKCS11</additionalJarsignerParameter>
                    <additionalJarsignerParameter>-tsa</additionalJarsignerParameter>
                    <additionalJarsignerParameter>http://timestamp.globalsign.com/scripts/timestamp.dll</additionalJarsignerParameter>
                    <additionalJarsignerParameter>-providerClass</additionalJarsignerParameter>
                    <additionalJarsignerParameter>sun.security.pkcs11.SunPKCS11</additionalJarsignerParameter>
                    <additionalJarsignerParameter>-providerArg</additionalJarsignerParameter>
                    <additionalJarsignerParameter>${project.basedir}/src/main/resources/token/eToken.config</additionalJarsignerParameter>
                    <!-- I DO KNOW that this is verbose ... -->
                </additionalJarsignerParameters>

                <!-- the jnlp-bundler gets a bit messy, lots of files, so we want to mimic "jfx:web"-folder-structure -->
                <nativeOutputDir>${project.build.directory}/jfx/web</nativeOutputDir>
            </configuration>
        </execution>
    </executions>
</plugin>

此版本尚未发布,但可从sonatype-repository以SNAPSHOT的形式提供。

答案 2 :(得分:0)

为什么不使用javafxpackager?它可以创建java webstart和可执行表单,并轻松签名。它是Oracle推荐的。我已经这么多年了,非常喜欢它。我正在使用它的ant任务,但我相信他们也有一个maven插件。

以下是更多信息:

http://docs.oracle.com/javafx/2/deployment/packager.htm