FibreFoX / javafx-gradle-plugin

Gradle plugin for JavaFX
Apache License 2.0
427 stars 59 forks source link

How to sign the jar/bundle #56

Closed chris-scorpio closed 7 years ago

chris-scorpio commented 7 years ago

Firstly, thanks for all the hard work you've put into this plugin.

Have been trying to figure out how to get the jar/mac bundle to be signed using an existing keystore. The corresponding command in javapackager would be -signjar. Looking at the code I can see that JNLP jars are signed and that a keystore can be created but can't see anything for normal jars/bundles.

Looks like the signing for windows bundles is separate from javapackager.

Can you point me in the right direction please.

FibreFoX commented 7 years ago

REMOVED

FibreFoX commented 7 years ago

Oh wait a minute ... thats not true ... sorry, will check for it ;)

FibreFoX commented 7 years ago

@chris-scorpio Hi there, sorry for the confusion on the answers before.

You are right, the signing-process is only applied for JNLP-files when using this plugin, but it is not the signing that you want! The javapackager introduced a method called BLOB Signing, which gets removed from the JDK9 (it never got grip in the ecosystem, nor tool-support to check the signature!!), this means that the corresponding command is not what you are expecting.

Just a stupid question: what is your use-case for having signed jar-files, when you are required to have the native launcher being signed on Mac?

Having your jars being signed can get archieved by using the normal signing-plugin provided by gradle itself: https://docs.gradle.org/current/userguide/signing_plugin.html

There is no built-in step for signing jars using the jfxJar-Task .... and I'm starting to think about it ;)

chris-scorpio commented 7 years ago

Thanks for the responses.

The company I work for is requesting that the win/mac/linux app/installers are signed so have spent the last couple of days looking into various methods, just assumed that the jars themselves also needed signing [will look into the gradle signing plugin for this].

FibreFoX commented 7 years ago

Oh, if it is only about the installers, you are not looking for signing the JAR, but the EXE/MSI/DEB/RPM-installers/native launchers? Don't know about your requirements, but are you sure you want to sign the JARs and not the native launchers/installers?

FibreFoX commented 7 years ago

Just some of my thoughts:

;D maybe you could try to describe what you really need

FibreFoX commented 7 years ago

One additional observation: the packager.dll-file is UNSIGNED, this is the first library loaded by the native launcher (I don't care for the runtime-msvc*.dll-files) ... this might be worthy to be reported as a bug on the oracle-bugtracker. This means: this is a file where some "strange mutation" could happen to "break" your signed native launcher ... in the case you aren't signing stuff that is not yours.

chris-scorpio commented 7 years ago

Hmm, some sound reasoning, I guess my need is for just the launcher [e.g. .app to keep mac gatekeeper happy] and the installers [e.g. to prevent windows pop-up to show it's not verified] to be signed.

So I guess the question is, does the wrapper plugin allow me to sign the mac installer [due to the phrasing of the -nosign in the deploy command] or do I need to find other ways to achieve this?

Windows looks like I would definitely have to use other means [e.g. inno setup with a sign tool]

Thanks for your patience and guidance on this matter, am new to the signing/security side of applications.

FibreFoX commented 7 years ago

No problem, I'm not that familiar with mac signing myself, but I guess I got the main idea behind this and my be able to help here. (I'm involved into searching a working solution / the bug on the maven plugin at https://github.com/javafx-maven-plugin/javafx-maven-plugin/issues/268 and https://github.com/javafx-maven-plugin/javafx-maven-plugin/issues/235).

Regarding your Mac signing problem/question: the generated mac application file application.app will get signed, all you need to do is to call the jfxNative-task (only in that task that file/folder is created). You need to have some certificate installed on the build-system with the key/name starting with "Developer ID Application: ", this is used within the mac.app-bundler. In the case you need a special/fixed one, please set this inside your jfx-configuration:

jfx {
    bundleArguments = [
        'signBundle': true,
        'mac.signing-key-developer-id-app': 'Developer ID Application: XYZ'
    ]
}

If everything works, the javapackager will use the native codesign-executable to sign your generated javafx-app-bundle.

For signing pkg-Installers on mac, in addition you are required to have a different certificate being installed locally, which has the key/name starting with "Developer ID Installer: ", this is used within the pkg-bundler. In the case you need a special/fixed one, please set this inside your jfx-configuration:

jfx {
    bundleArguments = [
        'signBundle': true,
        'mac.signing-key-developer-id-app': 'Developer ID Application: XYZ',
        'mac.signing-key-developer-id-installer': 'Developer ID Installer: XYZ'
    ]
}

For DMG-Installers, there seems no such option being present in the bundler.

For the mac.appStore-bundler, there are a lot more signing-key-optons available, please read these in analogy to the things above:

jfx {
    bundleArguments = [
        'signBundle': true,
        'mac.signing-key-user-name': '', // defaults to empty string, is used in the other bundlers too
        'mac.signing-keychain': '', // defaults to empty string, is used in the other bundlers too
        'mac.signing-key-developer-id-app': 'Developer ID Application: XYZ',
        'mac.signing-key-app': '3rd Party Mac Developer Application: XYZ',
        'mac.signing-key-pkg': '3rd Party Mac Developer Installer: XYZ'
    ]
}

When developing for Mac, you should recognize some of these certificate names ;)

For linux I'm unsure if such mechanism exists like signed executables ... never touched that area, does it exist? Is it a myth? ;D

For windows you are required to sign them afterwards, some quick google search for MSI-installers, which has to be called outside of the javafx-gradle-plugin. Maybe it is possible as part of the WiX- or InnoSetup-buildfiles, I don't know that.

I hope I could help you finding the right thing.

chris-scorpio commented 7 years ago

Thanks for info, the bundle arguments helped me out alot along with reading up loads on certificates etc.

FibreFoX commented 7 years ago

Does that mean this issue can be closed?

chris-scorpio commented 7 years ago

Yes it can be closed, but one last question - where did you see the parameter for signBundle as couldn't see it in the javapackager arguments section?

FibreFoX commented 7 years ago

The javapackager is the tool from the JDK, which accesses the internal libs, but the javafx-gradle-plugin accesses that API directly, like the javapackger does, which means that all CLI-parameters are not mapped one-to-one.

For finding all arguments, I have to look at the sourcecode of the bundlers. Some arguments are normal parameters, mosty ones which are often-used ones, and the others have to be provided via that special bundleArguments-property. There are 4 types of special bundlers, and one "PackagerLib" (which is responsible for creating that jfx-jar). You can look at the sourcecode where each type of bundler, sometimes it is hard to find them, because of inheritance.

bwRavencl commented 6 years ago

@FibreFoX first of all excuse me for summoning this already closed issue, but I have a question regarding your following statement, and maybe you can help me out here.

What is the idea of having SIGNED JARs when having native launchers? As far as I can tell, there is no benefit, as the native launcher loads the (bundled or locally installed) JRE via native library loading and runs your JAR-files normally. No technical benefit

I'm currently in the process of getting familiar with deploying Java apps as self contained applications, i.e. shipping a client application as an MSI with a self contained JVM. How can I assure that nobody is tampering with the jar files that are shipped with the native launcher? Shouldn't there be a way for the native launcher to verify a potential signature of the jars included in the application? I just did a quick test and replaced the jar file of my app with a modified one, containing some extra (potentially malicious) piece of code and the launcher ran it without complaining. Is there really no standard way to prevent this by signing the jars or "bind" the executable in any way to the jars it has been delivered with?