Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build strong named assemblies #11

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

AArnott
Copy link

@AArnott AArnott commented Dec 26, 2024

This supports thomhurst/TUnit#1467

Note that for .NET Framework users, adding a strong name is a binary breaking change. This means an application will fail if it has a mix of Sourcy users where some assemblies were compiled against the strong named version and some were not. I wonder if you want to rev the version number in a particular way to reflect this.

@thomhurst
Copy link
Owner

@AArnott I asked AI and it says it's generally not a good idea to store .snk files publicly. Should these be stored in Azure or something instead?

When building a strongly signed nuget package, is it okay to have the .snk file public in the repository?

No, it's generally not okay to have your .snk file public in a repository when building a strongly signed NuGet package.

Here's why:

Security Risk: The .snk file contains your private key, which is used to sign your assembly and your NuGet package. If someone gets hold of this file, they can:

Impersonate You: Create assemblies or NuGet packages that appear to be signed by you.
Tamper with Your Code: Potentially replace your legitimate packages with malicious versions, leading users to install compromised software.
Damage Your Reputation: If malicious packages are distributed under your name, your reputation and trustworthiness could be severely damaged.
Best Practices: Security best practices strongly advise keeping private keys secret and protected. Publishing them in a public repository is a direct violation of these practices.

What to Do Instead:

Keep the .snk file private and secure:

Store it in a secure location, like a dedicated build server or a secure vault.
Use environment variables or configuration files to reference the .snk file during the build process.
Never commit it to source control.
Use a dedicated signing service (recommended for production):

Services like Azure Key Vault or other code signing solutions offer a more secure way to manage signing keys.
These services store keys securely and provide controlled access for signing.
Use a .gitignore file:

Add *.snk to your .gitignore file to prevent accidental commits of the private key file.
Delay Signing (as an alternative in some scenarios):

In some situations, such as open-source projects, you might use delay signing. This means the assembly is signed with only the public key during development and testing.
The final signing with the private key happens later, during the release process.
However, this should be carefully evaluated in the context of your project.
In Summary:

Treat your .snk file as a highly sensitive secret. Compromising it can have serious security and reputational consequences. Always prioritize the security of your private key and avoid exposing it in public repositories. Use secure storage and dedicated signing services whenever possible.

@AArnott
Copy link
Author

AArnott commented Dec 29, 2024

The AI response is based on very old guidance. If for historical reasons you want to maintain a perception with your users that only you can build assemblies with your strong name (e.g. as the .NET Framework itself still does), an author may choose to retain the private key for their strong name as a secret. But generally it's not treated that way any more.

Microsoft's official stance on strong naming points users to Authenticode signing for verifiability of authorship or source of a binary. Strong naming only serves two purposes nowadays:

  1. avoid simple name collisions with other assemblies that may have the same name
  2. allow being referenced by other assemblies that are strong named.

Both of the above apply to .NET Framework. However strong naming means nothing by default on .NET, whether you do it or not.

Then there's the open source angle: since .NET Framework does care about strong naming, if you don't disclose the private key you use for strong naming, others cannot in fact fork, build and replace your dll in their application because they will not be able to reproduce a strong named and signed dll that you built. So in the spirit of open source, when strong naming the private key should be disclosed with the code.

The AI response is appropriate treatment for an authenticode private key, to be sure. But strong name private keys aren't for privacy or security at all (as Microsoft's guidance now states), but rather just a necessity for historical reasons in order to strong name sign, and thus are not harmed at all by being made public.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants