首页 > 解决方案 > Corda 默认对构建的 jar 进行签名,但坚持我应该添加签名凭据或将 enable 设置为 false

问题描述

我已经克隆了 corda-training-template repo 并想在 Corda v4.x 中测试签名约束。为了方便起见,我不会使用测试密钥来签署 jar,而是使用默认的 corda dev 密钥。但是我的理解是,如果您不输入任何自定义凭据,则默认使用 corda dev 密钥,以便所有 jar 都使用它进行签名。但是,它在构建过程中不断打印出错误消息:

 * What went wrong:
 Execution failed for task ':kotlin-source:jar'. > Exception while signing kotlin-source-0.1.jar, ensure the 'cordapp.signing.options' entry contains correct keyStore configuration, or disable signing by 'cordapp.signing.enabled false'. Run with --info or --debug option and search for 'ant:signjar' in log output. 

以下是 kotlin-source 的原始 build.gradle 删除了签名启用错误:

repositories {
mavenLocal()
jcenter()
mavenCentral()
maven { url 'https://dl.bintray.com/kotlin/exposed' }
maven { url 'https://jitpack.io' }
maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda-releases' }
}

apply plugin: 'kotlin'
apply plugin: 'idea'
apply plugin: 'net.corda.plugins.cordapp'
apply plugin: 'net.corda.plugins.publish-utils'
apply plugin: 'net.corda.plugins.cordformation'
apply plugin: 'net.corda.plugins.quasar-utils'
apply plugin: 'maven-publish'

cordapp {
targetPlatformVersion 4
minimumPlatformVersion 3
    contract {
        name "Corda Training Material"
        vendor "R3"
        licence "Contact R3 for Kotlin Source Contract License."
        versionId 1
    }
    workflow {
        name "Corda Training Material"
        vendor "R3"
        licence "Contact R3 for Kotlin Source Workflow License."
        versionId 1
    }
}

sourceSets {
    main {
        resources {
            srcDir "../config/dev"
         }
    }
    test {
        resources {
            srcDir "../config/test"
        }
    }
}

dependencies {
     compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
     testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
     testCompile "junit:junit:$junit_version"

     // Corda integration dependencies
     cordaCompile "$corda_release_distribution:corda-core:$corda_release_version"
     cordaCompile "$corda_release_distribution:corda-finance-contracts:$corda_release_version"
     cordaCompile "$corda_release_distribution:corda-finance-workflows:$corda_release_version"
     cordaCompile "$corda_release_distribution:corda-jackson:$corda_release_version"
     cordaCompile "$corda_release_distribution:corda-rpc:$corda_release_version"
     cordaCompile "$corda_release_distribution:corda-node-api:$corda_release_version"
     cordaCompile "$corda_release_distribution:corda-webserver-impl:$corda_release_version"
     cordaRuntime "$corda_release_distribution:corda:$corda_release_version"
     cordaRuntime "$corda_release_distribution:corda-webserver:$corda_release_version"

     testCompile "$corda_release_distribution:corda-test-utils:$corda_release_version"
     testCompile "$corda_release_distribution:corda-node-driver:$corda_release_version"


      // GraphStream: For visualisation (required by TemplateClientRPC app)
      compile "org.graphstream:gs-core:1.3"
      compile("org.graphstream:gs-ui:1.3") {
      exclude group: "bouncycastle"
      }

      // CorDapp dependencies
      // Specify your cordapp's dependencies below, including dependent cordapps
      cordapp "$corda_release_distribution:corda-finance-contracts:$corda_release_version"
      cordapp "$corda_release_distribution:corda-finance-workflows:$corda_release_version"
      cordapp "$corda_release_distribution:corda-confidential-identities:$corda_release_version"
}

tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
      kotlinOptions {
           languageVersion = "1.2"
           apiVersion = "1.2"
           jvmTarget = "1.8"
           javaParameters = true   // Useful for reflection.
      }
}

task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
      delete "./build/nodes"
      directory "./build/nodes"

      nodeDefaults {

            cordapp("$corda_release_distribution:corda-finance-contracts:$corda_release_version")
            cordapp("$corda_release_distribution:corda-finance-workflows:$corda_release_version")
            cordapp("$corda_release_distribution:corda-confidential-identities:$corda_release_version")
            rpcUsers = [[ user: "user1", "password": "password", "permissions": ["ALL"]]]
      }

      node {
           name "O=Notary,L=London,C=GB"
           notary = [validating: false]
           p2pPort 10002
           rpcSettings {
                 useSsl false
                 standAloneBroker false
                 address "0.0.0.0:10003"
                 adminAddress "0.0.0.0:10103"
           }
      }
      node {
           name "O=ParticipantA,L=London,C=GB"
           p2pPort 10007
           webPort 10009
           rpcSettings {
                 useSsl false
                 standAloneBroker false
                 address "0.0.0.0:10008"
                 adminAddress "0.0.0.0:10108"
           }
     }
     node {
          name "O=ParticipantB,L=New York,C=US"
          p2pPort 10010
          webPort 10012
          rpcSettings {
                 useSsl false
                 standAloneBroker false
                 address "0.0.0.0:10011"
                 adminAddress "0.0.0.0:10111"
          }
     }
     node {
          name "O=ParticipantC,L=Paris,C=FR"
          p2pPort 10013
          webPort 10015
          rpcSettings {
                 useSsl false
                 standAloneBroker false
                 address "0.0.0.0:10014"
                 adminAddress "0.0.0.0:10114"
          }
     } 
 }

 idea {
      module {
          downloadJavadoc = true // defaults to false
          downloadSources = true
      }
 }

为了响应错误消息,我在两个cordapp(https://docs.corda.net/releases/release-V4.0/cordapp-build-systems.html#signing-the -cordapp-jar)和 deployNodes (https://docs.corda.net/releases/release-V4.0/generating-a-node.html#signing-cordapp-jars)任务在不同的排列,但相同的错误消息询问对于正确的密钥库配置不断出现:

 signing {
       enabled true
       options {
            keystore 
            alias
            storepass
            storetype
            keyalg
       }
 }

如果没有提及密钥库的凭据,甚至没有指定签名选项,corda 应该使用默认的 corda dev 密钥构建 jar,但事实并非如此。

标签: corda

解决方案


首先,错误消息具有误导性,并没有准确说明 java jarsigner 工具中发生的事情(请参阅 ant signjar)。相反,jar 可能存在问题,导致 jarsigner 无法签名。SignJar.kt(第 23 到 24 行)在corda core plugin遇到错误时会抛出一般错误消息,因此需要使用 --info 或 --debug 模式运行 jar 任务,然后扫描消息以查找 [ant :signjar]。

在我使用 --debug 模式运行 jar 签名任务之后,我遇到了以下错误消息:

 01:00:15.040 [INFO] [org.gradle.api.internal.project.ant.AntLoggingAdapter] [ant:signjar] jarsigner: unable to sign jar: java.util.zip.ZipException: duplicate entry: META-INF/LICENSE.txt

问题可能是在尝试 fatjar(与其他库)时,来自其他 jar 的许可证文件导致冲突。在我的情况下,解决方案是从我的构建中排除许可证文件。将以下内容添加到 build.gradle jar 任务中。

 jar {
     duplicatesStrategy = DuplicatesStrategy.EXCLUDE
 }

构建 jar 后,我使用 jarsigner 工具(包含在您的 JDK 中)来验证 jar 是否已签名。

 jarsigner -verify <your jar.file name>

如果已签名,它将输出以下内容:

 jar verified.

 Warning:
 This jar contains entries whose certificate chain is not validated.
 This jar contains entries whose signer certificate will expire within six months.

 This jar contains signatures that does not include a timestamp. Without a timestamp, users may not be able to validate this jar after the signer certificate's expiration date (2019-11-26) or after any future revocation date.

 Re-run with the -verbose and -certs options for more details.

推荐阅读