问题
I distribute a Java application for MacOS, it is developer signed but not notarized. Not really sure where to start with this since the documentation is so biased towards creating apps with Xcode that I do not use, but I just want the simplest way to notarize my app and then move on.
Reading the documentation I have a few concerns already:
I am currently using Java 8, is it possible to notarize a Java 8 app or do I need to move to Java 11. I would rather not move to Java 11 because it would cause problem on some other platforms I support.
My dev Mac machine is an old MacBook Pro, and as such cannot be updated past OSX El Capitan 10.11.6, can I notarize with this machine or not? I do have a more recent machine but it is not setup for development and I have some concerns about transferring the Developer Id certificates to it because setting this up was problematic in first place.
I use the AppBundler fork https://github.com/TheInfiniteKind/appbundler/ to package my app
This is called by an ant script build file that does the signing etc, we eventually create a dmg using dmgCanvas
I post the ant script below, hoping someone can start me of with the basic steps
#!/bin/bash #set -x cd /Users/paul/code/jthink/songkong/src/main/scripts hiutil -C -fapplehelpbook/SongKongHelp/SongKongHelp.helpindex applehelpbook/SongKongHelp/ cd /Users/paul/code/jthink/songkong rm -fr /Applications/SongKong.app mvn clean mvn -DskipTests=true install rm -fr target/songkong-6.6 unzip target/songkong-6.6-distribution.zip -d target ant sudo cp -r target/songkong-6.6/applehelpbook/SongKongHelp /Applications/SongKong.app/Contents/Resources rm /Applications/SongKong.app/Contents/PlugIns/jdk1.8.0_192.jdk/Contents/MacOS/libjli.dylib cp /Applications/SongKong.app/Contents/PlugIns/jdk1.8.0_192.jdk/Contents/Home/jre/lib/jli/libjli.dylib /Applications/SongKong.app/Contents/PlugIns/jdk1.8.0_192.jdk/Contents/MacOS export CODESIGN_ALLOCATE="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/codesign_allocate" /usr/bin/codesign --sign "Developer ID Application: P Taylor" --force --deep --verbose /Applications/SongKong.app /usr/bin/codesign --verify --deep --verbose /Applications/SongKong.app cd /Users/paul/code/jthink/SongKong /usr/local/bin/dmgcanvas /Users/paul/code/jthink/SongKong/dmgCanvas_songkong.dmgCanvas /Users/paul/songkong-osx.dmg -v SongKong
回答1:
Edit 12/2/2020 - there have been a lot of changes because Apple have slowly tightened the requirements for notarization. From Feb 3rd they seem to have hit the final stage, which means your app has to meet much higher requirements, including a JRE which is built against the latest SDK and with "hardened runtime" support.
So I've stripped much of the old discussion.
My first issue was setting up - you need an active Developer Programme account with Apple ID (which is easy) but then, when you follow the instructions to add a password to the keychain, use the App specific password. You also need to enable two factor auth for your Apple ID account.
Once you work out the command line calls it's pretty easy to automate in a build script. I have used jpackage
to create the app and the DMG but beware - currently its approach to signing the app does not work.
In terms of scripting, here's what I'm doing to code sign the app suitable for notarization (this assumes a .app
is already created):
% security unlock-keychain -p passwordhere codesigning.keychain
% find my-app.app -type f \
-not -path "*/Contents/runtime/*" \
-not -path "*/Contents/MacOS/my-app" \
-not -path "*libapplauncher.dylib" \
-exec codesign --timestamp --entitlements /tmp/bliss.entitlements -s "XXX" --prefix com.myapp. --options runtime -v --keychain /path/to/codesigning.keychain {} \;
% find my-app.app/Contents/runtime -type f \
-not -path "*/legal/*" \
-not -path "*/man/*" \
-exec codesign -f --timestamp --entitlements /tmp/bliss.entitlements -s "XXX" --prefix com.myapp. --options runtime -v --keychain /path/to/codesigning.keychain {} \;
% codesign -f --timestamp --entitlements /tmp/bliss.entitlements -s "XXX" --prefix com.myapp. --options runtime -v --keychain /path/to/codesigning.keychain my-app.app/Contents/runtime
% codesign -f --timestamp --entitlements /tmp/bliss.entitlements -s "XXX" --prefix com.myapp. --options runtime -v --keychain /path/to/codesigning.keychain my-app.app
The entitlements should be:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.disable-executable-page-protection</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
</dict>
</plist>
All tests work:
% codesign -vvv --deep --strict my-app.app/Contents/runtime
my-app.app/Contents/runtime: valid on disk
my-app.app/Contents/runtime: satisfies its Designated Requirement
% codesign -vvv --deep --strict my-app.app/
--prepared:/private/tmp/my-app.app/Contents/MacOS/libapplauncher.dylib
--validated:/private/tmp/my-app.app/Contents/MacOS/libapplauncher.dylib
my-app.app/: valid on disk
my-app.app/: satisfies its Designated Requirement
% spctl -a -t exec -vv my-app.app
my-app.app: accepted
source=Developer ID
origin=XXX
At this point you should also try running your app - the code signing process can break things.
From here, you can create a DMG (again, I use jpackage
) and this should pass notarization.
In summary:
- Build the app in the correct structure
- Create an entitlements file
- Code sign your code
- Code sign the files inside bundled runtime, forcing the signature
- Code sign the bundled runtime itself
- Code sign your app file
- Package into a DMG
- Notarize it
- Ship it
回答2:
AFAIK, you need Java 11 (see JDK-8223671), however, recently I was told that Java 8 may also work. I haven't tried this.
JDK-8223671 contains some useful information. Specifically, you need to add entitlements to your code sign call:
codesign --entitlements java.entitlements --options runtime --deep -vvv -f --sign "Developer ID Application: Bla Bla (XXXX)" YourApp.app
A working sample java.entitlements
file could look like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.disable-executable-page-protection</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
</dict>
</plist>
Bundling a
jlink
generated runtime is a pain, because it contains sym links (which aren't allowed during signing) and also a legal folder that contains folder names likejava.xml
(with a.
).codesign
is unfortunately a little dumb and believes such folders are unrecognized bundles and aborts. Therefore you should rename those files/folders and resolve any sim links before jlinking.If you use
jlink
, make sure you add needed service providers, e.g., jdk.crypto.ec for HTTPS. Also note that AFAIK, in Java 11 TLSv1.3 is at least partially broken (upload of large files) and you should disable it, e.g. with-Dhttps.protocols=TLSv1.1,TLSv1.2
.If you use the AppBundler fork, you will need to make sure it also adheres to Apple's guidelines, i.e., is linked against macOS 10.9. I believe by default AppBundler links against 10.7, but changing it is simple.
If you are using Java 11 or later, make sure that you bundle
libjli.dylib
in/Contents/PlugIns/JAVA_PLUGIN_NAME/Contents/Home/lib/jli/libjli.dylib
. Apparently that's needed by the launcher and may not be bundled by default.Some of your other questions are answered in Apple's guidelines:
Notarization requires Xcode 10 or later. Building a new app for notarization requires macOS 10.13.6 or later. Stapling an app requires macOS 10.12 or later.
回答3:
To notarize requires Xcode 10, and to staple requires at least Sierra.
“Notarization requires Xcode 10 or later. Building a new app for notarization requires macOS 10.13.6 or later. Stapling an app requires macOS 10.12 or later.” https://developer.apple.com/documentation/security/notarizing_your_app_before_distribution
As for transferring dev certs, let Xcode handle this task by exporting your profile on the old machine and importing it on the new one.
回答4:
Update as of 3rd Feb 2020 Apple have tightened the notarization requirements, answer rewritten.
Note:I required the AdoptJdk Java 11.0.7 JRE, earlier versions did not work for me.
These are my steps
- Setup new machine (setup src code ectera)
- Install XCode then go to Preferences:Downloads and select Install Command Line Tools
- Using KeyChain Export Developer Id Certificate as .p12 format and import into new machine
- Purchase and install DmgCanvas 3 ($30USD)
- Renew Apple Developer Account
- Setup two-step authorisation for my AppleId account (this is partly done on website and partly with iCloud app)
- Create app specific password (make a note will need for dmgCanvas options)
- Install AdoptJdk Java 11.0.7 for building
- Install AdoptJdk Java 11.0.7 JRE for bundling inside app
- Create
songkong.entitlements
file - Configure build.xml file used by Appbundler InfiniteKind fork to refer directly to the AdoptOpenJDK JRe build
- Configure build script to sign the bundle created by appbundler, ensuring we use the new signing options required (e.g -runtime, --entitlements, --timestamp)
- The build script then create a dmg using dmgCanvas, and this additionally signs the dmg and sends it to Apple for notarization
build.xml includes:
<runtime dir="/Library/Java/JavaVirtualMachines/adoptopenjdk-11.jre/Contents/Home"/>
buildosx.sh is
#!/bin/bash
#set -x
cd /Users/paul/code/jthink/songkong
sudo rm -fr /Applications/SongKong.app
mvn -f pommacos.xml -DskipTests=true install
rm -fr target/songkong-6.9
unzip target/songkong-6.9-distribution.zip -d target
ant
export CODESIGN_ALLOCATE="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/codesign_allocate"
/usr/bin/codesign --timestamp --options runtime \
--entitlements /Users/paul/code/jthink/songkong/songkong.entitlements \
--sign "Developer ID Application: P Taylor" \
--force --deep --verbose /Applications/SongKong.app
/usr/bin/codesign -vvv --deep --strict /Applications/SongKong.app
spctl -a -t exec -vv /Applications/SongKong.app
cd /Users/paul/code/jthink/SongKong
/usr/local/bin/dmgcanvas /Users/paul/code/jthink/SongKong/dmgCanvas_songkong.dmgCanvas \
/Users/paul/songkong-osx.dmg \
-v SongKong -identity "Developer ID Application: P Taylor" \
-notarizationAppleID paultaylor@jthink.net \
-notarizationPassword password \
-notarizationPrimaryBundleID songkong
SongKong entitlements file is:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.disable-executable-page-protection</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
</dict>
</plist>
Note:I have also tried this with referring to AdoptJdk Java 11.0.7 JDK build.xml and that also builds without issue (although of course end up witha much larger dmg)
来源:https://stackoverflow.com/questions/58548736/notarize-existing-java-application-for-macos-catalina