公司只提供簽名服務,不提供證書檔案,如何打包Electron應用

liulun發表於2020-12-08

需求

稍微正規點的公司,都要為自己開發的軟體做程式碼簽名,如下圖所示

程式碼簽名的主要目的是為了確保軟體的來源(這個軟體是由誰生產的)和軟體的內容不被篡改

一個軟體公司可能有很多團隊,很多開發者,開發不同的軟體,但用於簽名的證照就那麼一套

由於擔心開發者用這個證照去簽名惡意的軟體,損壞公司的聲譽,

所以這套證照一般不會直接給開發者使用的

那麼怎麼辦呢?

公司往往會開發一個服務,

軟體開發好後,開發者把軟體上傳到這個服務上,由這個服務給軟體簽名,簽完名後,開發者再下載簽名後的檔案,再分發給使用者

方案

如果公司提供的簽名服務是標準的CI簽名服務,那麼開發者只要為electron-builder設定CSC_LINK和CSC_KEY_PASSWORD環境變數即可

但往往公司提供的就是一個簡單的http上傳下載服務,

這就需要通過自定義electron-builder的簽名回撥來完成相應的工作了

下面是這個配置項在整個electron-builder配置項中的位置(此文簽名只與windows環境有關):

let options = {
      config: {
        win: {
          sign: async (config) => {
            
          }
        },
      },
}
builder.build(options);

在electron-builder為應用打包時,

至少會產出4個可執行檔案(windows平臺下為exe檔案)

  • 你的應用程式.exe
  • 你的應用程式的安裝檔案.exe
  • 你的應用程式的解除安裝檔案.exe
  • elevate.exe(這個檔案用於以管理員的身份啟動程式)

上面提到的sign函式會相應的執行8次(每個exe檔案產生時,會執行兩次sign函式)

如果你有其他的可執行程式要打包到你的應用中,

相應的sign函式也會被呼叫(同樣也是每個exe檔案,會執行兩次sign函式)

sign函式被呼叫時,electron-builder會為其輸入一個config引數

這個引數的值如下(兩個物件分別對應兩次呼叫):

{
  path: 'D:\\project\\***\\*** 1.3.0.exe',
  name: 'HikLink',
  site: null,
  options: {
    icon: '../resource/unrelease/icon.ico',
    target: [ [Object] ],
    sign: [AsyncFunction: sign]
  },
  hash: 'sha1',
  isNest: false,
  computeSignToolArgs: [Function: computeSignToolArgs]
}
{
  path: 'D:\\project\\***\\*** 1.3.0.exe',
  name: 'HikLink',
  site: null,
  options: {
    icon: '../resource/unrelease/icon.ico',
    target: [ [Object] ],
    sign: [AsyncFunction: sign]
  },
  hash: 'sha256',
  isNest: true,
  computeSignToolArgs: [Function: computeSignToolArgs]
}

不同點是:hash和isNest兩個屬性

(有兩種簽名型別,一種是sha1,一種是sha256,sha1由於不安全,基本已經廢棄了,所以我們選擇sha256)

最終的sign函式的邏輯為:

child_process.spawnSync("curl.exe", [
              "-F",
              "auth_id=******",
              "-F",
              "username=******",
              "-F",
              "fd=sha256",
              "-F",
              "file=@" + config.path,  //生成的exe檔案的絕對路徑
              "-F",
              "cert_type=SHA256",
              "http://******/sign.php", //簽名服務
              "-k",
              "-f",
              "-o",
              config.path   //簽名完之後就下載,下載之後就覆蓋
            ], {
              cwd: path.dirname(config.path),
              stdio: "inherit" //上傳下載過程同步到當前控制檯
            })

我們是使用著名的curl.exe完成這個工作的

當然可以自己寫程式碼模擬表單提交過程

PS

如果公司需要把所有的exe和dll都簽名,那麼就需要另外想辦法了

我曾經把electron-builder裡的程式碼改寫了,就為了滿足簽名的要求,真是一把辛酸淚

 

相關文章