-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
how to do Code Signing via esigner from ssl.com without USB Token? #6158
Comments
I've done it, was going to do a writeup and submit a PR to the docs but since you have a pressing need, I'll just throw out what I have now. I read through all the windows sign/singing on Unix etc. and you don't need much of it with this CodeSignTool. This was the most useful part and the basis for what I ended up doing. After you have your certs paid for (and I assume you are using the team feature, were each user can have their own login)...
This example uses these values running under process.env, you can devise your own way to set these values, but for example sake, we'll just prepend them to our
You will need to update your electron builder section, it no longer needs the
And here's the
Let me know if you have any questions etc. |
Christopher you're a hero, thank you very much! INFO ISSUE 1 ISSUE 2
const moveFile = `move "${tempFile}.exe" "${dir}"`; Seems ok in case we're signing .exe files only ISSUE 3 IDEA |
This is some good feedback, like I said, I wasn't quite ready to write this stuff up so I knew there would be issues.
|
It's a few months ago, now SSL.com changed it and the service is now not free anymore.. Seems they want a subscription fee. Not very cool if you need signing your app only few times a year.. Is there any other solution on the market for signing apps on Github actions with an EV code signing certificate without a usb dongle? |
Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward? This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. |
Thanks for this! One more small tweak: The temp dir creation didn't work for me, but this does:
|
Hey does the ssl.com code signing certificate still work to sign electron apps? I'm trying to build an electron app that has code signing and I'm considering this code signing certificate: Thanks |
@arjun-formicsio I managed to do SSL.com eSigner signing in a much simpler manner using the codesign support in electron-builder along with SSL.com's Cloud Key Adapter. You can see it at https://github.com/vector-im/element-desktop/blob/develop/.github/workflows/build_windows.yaml#L118-L163 |
Yes |
Thanks, this was very useful 🤷♂️. For those using this approach, make sure that you specify |
Do you have an idea to do the same procedure with Electron Forge? Like, as per their doc, they are asking .pfx certificate, which ssl.com won't issue? |
@rajjagani021 Sadly no, the trick in |
I tried with the above solution but its giving some error like bellow The system cannot find the path specified. |
3 days of trying to figure this out, so I figured I'd provide detailed instructions for anyone else coming across this: By far the easiest way I've found of signing with the SSL.com eSigner and electron-builder is to use their Github Action, but not directly from within a Github Actions step, but from within the build process. The benefit of using their Github Action is that it downloads and configures all of the right software for you directly on the github runner with zero involvement on your end, with the latest version, and cross-platform. Because electron-builder cannot "pause" its build process for you to sign in a separate Github Action step, you have to call the eSigner from within the build process javascript directly. Here's how:
Billing alert: Here's how I do this: In your github actions config file (e.g. build.yml):# download 'SSLcom/esigner-codesign' to a folder called 'esigner-codesign' in the root of the project
- name: Checkout esigner-codesign repository (Windows)
if: contains(matrix.os, 'windows')
uses: actions/checkout@v3
with:
repository: 'SSLcom/esigner-codesign'
path: esigner-codesign
# builds, signs, and publishes - actual signing happens within electron-builder.js
- name: Publish (Windows)
if: contains(matrix.os, 'windows')
run: npm run build && npx electron-builder build --config electron-builder.js -p always
env:
GH_TOKEN: ${{ secrets.GITHUB_ACCESS_TOKEN }}
# NOTE: must explicitly pass in even the parameters that esigner-codesign says are optional since we're not using the action directly, but rather passing the params in as env vars:
CODE_SIGN_SCRIPT_PATH: "${{ github.workspace }}/esigner-codesign/dist/index.js"
INPUT_COMMAND: "sign"
INPUT_FILE_PATH: "${{ github.workspace }}/dist/REPLACE_WITH_YOUR_APP_NAME Setup ${{ needs.get-versions.outputs.package_version }}.exe"
INPUT_OVERRIDE: "true"
INPUT_MALWARE_BLOCK: "false"
INPUT_CLEAN_LOGS: "false"
INPUT_JVM_MAX_MEMORY: "1024M"
INPUT_ENVIRONMENT_NAME: "PROD"
INPUT_USERNAME: ${{ secrets.SSL_COM_USERNAME }}
INPUT_PASSWORD: ${{ secrets.SSL_COM_PASSWORD }}
INPUT_TOTP_SECRET: ${{ secrets.SSL_COM_TOTP_SECRET }}
INPUT_CREDENTIAL_ID: ${{ secrets.SSL_COM_CREDENTIAL_ID }} Then in your electron-builder.jsconst { execSync } = require('child_process');
const config = {
// your config goes here
win: {
target: [
"nsis"
]
},
}
if (process.env.CODE_SIGN_SCRIPT_PATH) {
// Dynamically get the version number from package.json
const version = execSync('node -p "require(\'./package.json\').version"').toString().trim();
const versionedExe = `REPLACE_WITH_YOUR_APP_NAME Setup ${version}.exe`;
config.win.sign = (configuration) => {
console.log("Requested signing for ", configuration.path);
// Only proceed if the versioned exe file is in the configuration path - skip signing everything else
if (!configuration.path.includes(versionedExe)) {
console.log("Configuration path does not include the versioned exe, signing skipped.");
return true;
}
const scriptPath = process.env.CODE_SIGN_SCRIPT_PATH;
try {
// Execute the sign script synchronously
const output = execSync(`node "${scriptPath}"`).toString();
console.log(`Script output: ${output}`);
} catch (error) {
console.error(`Error executing script: ${error.message}`);
if (error.stdout) {
console.log(`Script stdout: ${error.stdout.toString()}`);
}
if (error.stderr) {
console.error(`Script stderr: ${error.stderr.toString()}`);
}
return false;
}
return true; // Return true at the end of successful signing
};
// sign only for Windows 10 and above - adjust for your code as needed
config.win.signingHashAlgorithms = ["sha256"];
}
module.exports = config; One important bit, notice the
Thanks @HyperSprite for the useful reference code on how to do custom signing! |
For completeness, if you wanted to more heavily leverage the code signing support in electron-builder with no custom signing script you can use the eSigner CKA: |
Thanks @yuvalkarmi! This approach worked for me, just wanted to leave some issues that I had here in case it helps someone else:
So my const { execSync } = require('child_process');
const config = {
// your config goes here
win: {
target: [
"nsis"
]
},
}
if (process.env.CODE_SIGN_SCRIPT_PATH) {
console.log('CODE_SIGN_SCRIPT_PATH found in env vars:', process.env.CODE_SIGN_SCRIPT_PATH);
config.win.sign = configuration => {
console.log('Requested signing for ', configuration.path);
// Only proceed if the versioned .exe file is in the configuration path - skip signing everything else
if (!/(\d+)\.(\d+)\.(\d+)-win-x64.exe$/.test(configuration.path)) {
console.log('This is not the versioned .exe, skip signing');
return true;
}
const scriptPath = process.env.CODE_SIGN_SCRIPT_PATH;
try {
// Execute the sign script synchronously
process.env.INPUT_COMMAND = 'sign';
process.env.INPUT_FILE_PATH = configuration.path;
const env = {
command: process.env.INPUT_COMMAND,
username: process.env.INPUT_USERNAME,
password: process.env.INPUT_PASSWORD,
credential_id: process.env.INPUT_CREDENTIAL_ID,
totp_secret: process.env.INPUT_TOTP_SECRET,
file_path: process.env.INPUT_FILE_PATH,
output_path: process.env.INPUT_OUTPUT_PATH,
malware_block: process.env.INPUT_MALWARE_BLOCK,
override: process.env.INPUT_OVERRIDE,
clean_logs: process.env.INPUT_CLEAN_LOGS,
environment_name: process.env.INPUT_ENVIRONMENT_NAME,
jvm_max_memory: process.env.INPUT_JVM_MAX_MEMORY,
};
console.log('env:', JSON.stringify(env, null, 2));
const output = execSync(`node "${scriptPath}"`, {
env: { ...process.env, ...env },
}).toString();
console.log(`Script output: ${output}`);
} catch (error) {
console.error(`Error executing script: ${error.message}`);
if (error.stdout) {
console.log(`Script stdout: ${error.stdout.toString()}`);
}
if (error.stderr) {
console.error(`Script stderr: ${error.stderr.toString()}`);
}
return false;
}
return true; // Return true at the end of successful signing
};
// sign only for Windows 10 and above - adjust for your code as needed
config.win.signingHashAlgorithms = ['sha256'];
}
module.exports = config; |
thanks everyone for all their informative comments. i think i managed to make it work. i did a couple of tweaks to handle our particular weird setup. specific important notes
finally i got electron-builder to run locally and it outputted "Code signed successfully" here is permalink for my current github action my is permalink for my current sign.js |
A few months ago ssl.com launched "esigner" and a CLI tool called CodeSignTool. This allows to sign apps for windows without a USB Token, even with EV Code Signing what normally needs the USB Token. This is really cool, allows for instance to build an app on a hosted build server and allows to fully automate the build process, no Token PIN has to be entered manually during the building process.
I haven't find any information how to setup this with electron-bulder. Is there someone who already did it?
Of course it would be super cool if electron-bulder would support the CodeSignTool, no need for local certificate and usb token anymore.
The text was updated successfully, but these errors were encountered: