![](/img/trans.png)
[英]C# Windows Form Application not reading files correctly from Linux-based server
[英]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.