如何签署 Mac OS X 应用程序?

发布于 2024-10-23 15:46:06 字数 68 浏览 1 评论 0原文

我创建了一个 Mac OS X 应用程序,但我不知道必须执行哪些步骤才能正确签署我的 Mac OS X 应用程序。 谢谢。

I created a Mac OS X application but I don't know which steps I have to do for signing my Mac OS X application correctly.
Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

¢好甜 2024-10-30 15:46:06

我发现苹果文档太冗长了。我已经写了一些关于如何签署我自己的 Mac 软件的详细说明。内容太多,无法全部放在这里。看:
http:// successsoftware.net/2012/08/30/how-to-sign-your-mac-os-x-app-for-gatekeeper/

I found the Apple documentation far too verbose. I have written up some detailed notes on how I signed my own software for Mac. There is too much to put it all here. See:
http://successfulsoftware.net/2012/08/30/how-to-sign-your-mac-os-x-app-for-gatekeeper/

梦旅人picnic 2024-10-30 15:46:06

使用 Qt

macdeployqt APP_NAME.app -codesign="Developer ID Application: YOUR NAME (ID_NUMBERS)"

否则,

codesign --force --verify --verbose --sign "Developer ID Application: YOUR NAME (ID_NUMBERS)" APP_NAME.app

您还需要使用类似以下内容将每个框架和 dylib 文件签名到包中

codesign --force --verify --verbose --sign "Developer ID Application: YOUR NAME (ID_NUMBERS)" APP_NAME.app/Contents/Frameworks/QtCore.framework/Versions/5/QtCore
codesign --force --verify --verbose --sign "Developer ID Application: YOUR NAME (ID_NUMBERS)" APP_NAME.app/Contents/Plugins/bearer/libqcorewlanbearer.dylib

With Qt

macdeployqt APP_NAME.app -codesign="Developer ID Application: YOUR NAME (ID_NUMBERS)"

Otherwise

codesign --force --verify --verbose --sign "Developer ID Application: YOUR NAME (ID_NUMBERS)" APP_NAME.app

You also need to sign every framework and dylib file into the package with something like this

codesign --force --verify --verbose --sign "Developer ID Application: YOUR NAME (ID_NUMBERS)" APP_NAME.app/Contents/Frameworks/QtCore.framework/Versions/5/QtCore
codesign --force --verify --verbose --sign "Developer ID Application: YOUR NAME (ID_NUMBERS)" APP_NAME.app/Contents/Plugins/bearer/libqcorewlanbearer.dylib
标点 2024-10-30 15:46:06

首先,您需要一个功能齐全(因此需要付费)的 Apple 开发者帐户。
然后您可以按照以下信息操作: https:// /developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/Introduction/Introduction.html

上面的链接是全局过程,但有一个特定的主题,在下面清楚地说明了如何操作URL: https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/Procedures/Procedures.html#//apple_ref/doc/uid/TP40005929-CH4-SW2

At first you need an fully functional (and thus paid) Apple developer account.
Then you can follow this information: https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/Introduction/Introduction.html

The above link is the global procedure, but there is a specific topic with clean illustrated how to at the following URL: https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/Procedures/Procedures.html#//apple_ref/doc/uid/TP40005929-CH4-SW2

混吃等死 2024-10-30 15:46:06

苹果对此有很好的文档。转到开发人员配置部分,那里有一个很好的入门知识,可以让您快速运行。

There is good Apple documentation on this. Go to the developer provisioning section and there is a good primer there that can get you running quickly.

吲‖鸣 2024-10-30 15:46:06

当您对应用程序进行签名时,该应用程序内的所有可执行文件都需要进行签名,否则公证将失败。

我编写了这个节点代码,它将递归地查找应用程序中的所有可执行文件并对其进行签名。

#!/usr/bin/env node
// 5.14

const APP = "./yourAppName.app";
const IDENTITY = "your_signature_";

/****************************************************************************/
const items = [];
console.log("### finding things to sign");

const fs = require('fs');
const child_process = require('child_process');
const recursive = require("recursive-readdir");
const listdirs = require('listdirs');


const folder = `./nwjs.app`;

const main = async()=>{

    const allFiles = await recursive(folder);
    const exeFiles = allFiles.filter((x)=>{
        try {
            fs.accessSync(x, fs.constants.X_OK)
            return true;    
        } catch (error) {
            return false
        }
        
    })
    console.log("all files", exeFiles); 
    items.push(...exeFiles)

    const myListDir = (folder)=>{
        return new Promise((resolve, reject) => {
            listdirs(folder, function callback(err, list){
                if(err){
                  return reject(err)
                }
                else {
                  return resolve(list)
                }
            });         
        });
    }

    const allFolders = await myListDir(folder);
    const appFolders = allFolders.filter((x)=>{
        return x.endsWith(".app")
    })

   console.log("all Folders", appFolders); 
   items.push(...appFolders)


    /****************************************************************************/

    console.log("");
    console.log("### signing");

    function exec(cmd) {
        console.log(cmd);
        const result = child_process.spawnSync(cmd, {shell: true, stdio: 'inherit'});
        if (result.status !== 0) {
            console.log(`Command failed with status ${result.status}`);
            if (result.error) console.log(result.error);
            //process.exit(1);
        }
    }

    items.push(`${APP}/Contents/MacOS/nwjs`)
    
    
    for (const item of items) {
        try {
            exec(`codesign --verbose --force --deep --strict --options runtime --timestamp --sign "${IDENTITY}" --entitlements neededToRun.entitlements "${item}"`);    
        } catch (error) {
            console.log(error);
        }
        
    }

    exec(`codesign --verbose --force --deep --strict --options runtime --timestamp --sign "${IDENTITY}" --entitlements neededToRun.entitlements "${APP}"`);

    /****************************************************************************/

    console.log("");
    console.log("### verifying signature");

    exec(`codesign --verify -vvvv "${APP}"`);
}

main();

When you sign an app, all executables inside that app need to be signed, otherwise, the notarization will fail.

I wrote this node code that will recursively find all executables within an app and sign them.

#!/usr/bin/env node
// 5.14

const APP = "./yourAppName.app";
const IDENTITY = "your_signature_";

/****************************************************************************/
const items = [];
console.log("### finding things to sign");

const fs = require('fs');
const child_process = require('child_process');
const recursive = require("recursive-readdir");
const listdirs = require('listdirs');


const folder = `./nwjs.app`;

const main = async()=>{

    const allFiles = await recursive(folder);
    const exeFiles = allFiles.filter((x)=>{
        try {
            fs.accessSync(x, fs.constants.X_OK)
            return true;    
        } catch (error) {
            return false
        }
        
    })
    console.log("all files", exeFiles); 
    items.push(...exeFiles)

    const myListDir = (folder)=>{
        return new Promise((resolve, reject) => {
            listdirs(folder, function callback(err, list){
                if(err){
                  return reject(err)
                }
                else {
                  return resolve(list)
                }
            });         
        });
    }

    const allFolders = await myListDir(folder);
    const appFolders = allFolders.filter((x)=>{
        return x.endsWith(".app")
    })

   console.log("all Folders", appFolders); 
   items.push(...appFolders)


    /****************************************************************************/

    console.log("");
    console.log("### signing");

    function exec(cmd) {
        console.log(cmd);
        const result = child_process.spawnSync(cmd, {shell: true, stdio: 'inherit'});
        if (result.status !== 0) {
            console.log(`Command failed with status ${result.status}`);
            if (result.error) console.log(result.error);
            //process.exit(1);
        }
    }

    items.push(`${APP}/Contents/MacOS/nwjs`)
    
    
    for (const item of items) {
        try {
            exec(`codesign --verbose --force --deep --strict --options runtime --timestamp --sign "${IDENTITY}" --entitlements neededToRun.entitlements "${item}"`);    
        } catch (error) {
            console.log(error);
        }
        
    }

    exec(`codesign --verbose --force --deep --strict --options runtime --timestamp --sign "${IDENTITY}" --entitlements neededToRun.entitlements "${APP}"`);

    /****************************************************************************/

    console.log("");
    console.log("### verifying signature");

    exec(`codesign --verify -vvvv "${APP}"`);
}

main();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文