簡體   English   中英

在基於 Linux 的發行版上簽署 Windows 應用程序

[英]Signing Windows application on Linux-based distros

我准備了一個應用程序和網站,客戶可以在下載之前為此應用程序設置幾個選項。 設置以二進制格式存儲在文件的末尾(附加),然后將編輯后的文件發送給最終用戶。 問題是文件“內容”的更改會破壞文件簽名 - 是否有機會使用任何命令行工具重新簽署這個更改的文件? 我曾嘗試使用 Microsoft 的 SignTool,但它在 Linux 上無法正常工作。

你可以試試osslsigncode

要簽署 EXE 或 MSI 文件,您現在可以執行以下操作:

osslsigncode sign -certs <cert-file> -key <der-key-file> \
        -n "Your Application" -i http://www.yourwebsite.com/ \
        -in yourapp.exe -out yourapp-signed.exe

或者,如果您使用帶有密碼的 PEM 或 PVK 密鑰文件以及 PEM 證書:

osslsigncode sign -certs <cert-file> \
        -key <key-file> -pass <key-password> \
        -n "Your Application" -i http://www.yourwebsite.com/ \
        -in yourapp.exe -out yourapp-signed.exe

或者如果您還想添加時間戳:

osslsigncode sign -certs <cert-file> -key <key-file> \
        -n "Your Application" -i http://www.yourwebsite.com/ \
        -t http://timestamp.verisign.com/scripts/timstamp.dll \
        -in yourapp.exe -out yourapp-signed.exe

您可以使用存儲在 PKCS#12 容器中的證書和密鑰:

osslsigncode sign -pkcs12 <pkcs12-file> -pass <pkcs12-password> \
        -n "Your Application" -i http://www.yourwebsite.com/ \
        -in yourapp.exe -out yourapp-signed.exe

要簽署包含 java 類文件的 CAB 文件:

osslsigncode sign -certs <cert-file> -key <key-file> \
        -n "Your Application" -i http://www.yourwebsite.com/ \
        -jp low \
        -in yourapp.cab -out yourapp-signed.cab

使用Mono的簽名工具實際上非常簡單 棘手的部分(在鏈接的 Mozilla 文章中有更詳細的描述)是以正確的格式將證書從 Windows 復制到 Linux。

將Windows PFX證書文件轉換為PVK和SPC文件,從Windows復制證書到Linux時只需要做一次;

openssl pkcs12 -in authenticode.pfx -nocerts -nodes -out key.pem
openssl rsa -in key.pem -outform PVK -pvk-strong -out authenticode.pvk
openssl pkcs12 -in authenticode.pfx -nokeys -nodes -out cert.pem
openssl crl2pkcs7 -nocrl -certfile cert.pem -outform DER -out authenticode.spc

實際上簽署exe是直截了當的;

signcode \
 -spc authenticode.spc \
 -v authenticode.pvk \
 -a sha1 -$ commercial \
 -n My\ Application \
 -i http://www.example.com/ \
 -t http://timestamp.digicert.com/scripts/timstamp.dll \
 -tr 10 \
 MyApp.exe

如果您想在運行時以編程方式執行此操作,您可以使用Jsign工具。 特別是當您通過請求簽名后在后端生成可自行執行的存檔時,它可能會非常有用。 並且您顯然使用 Java/Kotlin 來做到這一點(該工具的名稱是建議的)。 這是官方網站提供的API:

只需將此依賴項添加到項目中:

 <dependency> <groupId>net.jsign</groupId> <artifactId>jsign-core</artifactId> <version>3.1</version> </dependency>

然后像這樣使用AuthenticodeSigner類:

 KeyStore keystore = KeyStoreUtils.load(newFile("keystore.p12"), "PKCS12", "password", null); AuthenticodeSigner signer = new AuthenticodeSigner(keystore, "test", "secret"); signer.withProgramName("My Application") .withProgramURL("http://www.example.com") .withTimestamping(true) .withTimestampingAuthority("http://timestamp.comodoca.com/authenticode"); Signable file = Signable.of(new File("application.exe")); signer.sign(file);

有關 API 的更多詳細信息,請參閱Javadoc

除了通過 Java KeyStore簽名之外, AuthenticodeSigner還具有(Certificate, PrivateKey)構造函數,您可以像我在“Spring on Kotlin”后端一樣自由使用它:

    @Bean
    fun certsChain(): Array<Certificate> {
        val fact: CertificateFactory = CertificateFactory.getInstance("X.509")
        val `is` = ResourceUtil.getResourceFileAsInputStream("cert/certificate.pem")
        val cer: X509Certificate = fact.generateCertificate(`is`) as X509Certificate
        return arrayOf(cer)
    }

    @Bean
    fun privateKey(): PrivateKey {
        var key = ResourceUtil.getResourceFileAsString("cert/privateKey.pem")
        key = key.replace("-----BEGIN PRIVATE KEY-----", "")
        key = key.replace("\n", "")
        key = key.replace("-----END PRIVATE KEY-----", "")
        val encoded = Base64.getDecoder().decode(key)
        val kf = KeyFactory.getInstance("RSA")
        val keySpec = PKCS8EncodedKeySpec(encoded)
        return kf.generatePrivate(keySpec) as RSAPrivateKey
    }

    @Bean
    fun signer(
            certs: Array<Certificate>,
            privateKey: PrivateKey
    ): AuthenticodeSigner =
            AuthenticodeSigner(certs, privateKey)
                    .withProgramName("Your Company Name")
                    .withProgramURL("https://something.com")
                    .withTimestamping(true)
                    .withTimestampingAuthority("http://timestamp.comodoca.com/authenticode");

之后,您只需@Autowire signer bean 並使用所需文件調用其方法sign()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM