Linux: convert pfx to snk - or: How to Strong-Name an Assembly

57 Views Asked by At

I am on Linux. The platform is a devcontainer, so the underlying os might vary.

I am using dotnet build to compile a .csproj project. (The .csproj is in the new sdk format.)

I need the resulting assembly to be strong-named. However, I only have a password protected .pfx file (and I know the password).

How do I convert that .pfx file into something the dotnet tool can digest on Linux?

Direct signing with .pfx does not seem to be supported. It seems I need a .snk file that is not password-protected. However, after spending several hours with Google and ChatGPT, I seem unable to find a way to create a .snk file that contains both the public and the private key from the .pfx file. And I am still unsure whether the .snk file is the correct way to go.

Can anyone here help me figure this out? Again, this is Linux, not Windows. On Windows this would be easy(er).

Platform:

  • some Linux os
  • mono installed (includes the sn tool)
  • OpenSSL installed
  • dotnet installed
  • PowerShell installed

Other open-source tools can be added if needed.

Input:

  • something.cs
  • something.csproj
  • aPasswordProtected.pfx

Output:

  • a strong-name signed .dll file

Process:

  • there are several possible paths to go from here. I don't have a preference at this point.
    • Convert the key, and reference the converted file in the .csproj file.
    • Convert the key. Use dotnet build to create unsigned Assembly. Use other tool to sign the assembly after the fact.
    • Use yet another tool alltogether to both compile and sign.

Also at this point I am not concerned with security. Let's get it working first. Then we can think about how to store unprotected key files safely.

1

There are 1 best solutions below

0
Sebastian Meine On

Got it. Creating a .snk file requires an intermediary step making a .pem file (without a password). Here is the PowerShell script:

& openssl pkcs12 -in "$pfxFilePath" -out "$pemFilePath" -nodes -passin pass:$pfxPassword

$rsa = New-Object System.Security.Cryptography.RSACryptoServiceProvider
$pemContent = Get-Content -Path "$pemFilePath" -Raw

$rsa.ImportFromPem($pemContent.ToCharArray())
$keyPair = $rsa.ExportCspBlob($true)

[System.IO.File]::WriteAllBytes($snkFilePath, $keyPair)

This .snk file you can directly reference in you .csproj file like this:

<PropertyGroup>
  <SignAssembly>true</SignAssembly> 
  <AssemblyOriginatorKeyFile>$(snkFilePath)</AssemblyOriginatorKeyFile>
</PropertyGroup>

Pass the $snkFilePath into dotnet like this (in PowerShell):

& dotnet build /p:snkFilePath=$snkFilePath