Sn Exe Generate Key Pair
title | ms.date | helpviewer_keywords | ms.assetid | ||
---|---|---|---|---|---|
03/30/2017 |
| c1d2b532-1b8e-4c7a-8ac5-53b801135ec6 |
If you do not specify a CSP name, Sn.exe clears the current setting.-d container: Deletes the specified key container from the strong name CSP.-D assembly1 assembly2: Verifies that two assemblies differ only by signature. This is often used as a check after an assembly has been re-signed with a different key pair.-e assembly outfile. To create a strong name key file we need to run the following command in comand prompt with the file name: sn -k sgKey.snk. After the public/private key pair is created,we need to provide the file name in the AssemblyInfo file of the project for whom we want to generate the strong name key. Using a development environment that supports creating strong names, such as Visual Studio. Creating a cryptographic key pair using the Strong Name tool (Sn.exe) and assigning that key pair to the assembly using either a command-line compiler or the Assembly Linker (Al.exe). The Windows SDK provides both Sn.exe and Al.exe. 32 rows Sn.exe computes the token by using a hash function from the public key. To save space, the runtime stores public key tokens in the manifest as part of a reference to another assembly when it records a dependency to an assembly that has a strong name. The -Tp option displays the public key in addition to the token. The sn.exe can generate the Public Key Token only from the Public Key file. Hence you have to first generate a Key Pair and then extract the Public Key. This Public Key is then passed to the sn.exe. Here are the steps for generation of Public Key and verification of its Token using sn.exe. Figure 2: Output from running the sn.exe utility to. Re-sign the assembly with the full identity key pair. Sn -Ra MyAssembly.exe IdentityKey.snk Sign with SHA-2, with key migration. Run the following commands from a command prompt to sign an assembly with a migrated strong name signature. Generate an identity and signature key pair (if necessary). Sn -k IdentityKey.snk sn -k SignatureKey.snk.
The Strong Name tool (Sn.exe) helps sign assemblies with strong names. Sn.exe provides options for key management, signature generation, and signature verification.
[!WARNING]Do not rely on strong names for security. They provide a unique identity only.
For more information on strong naming and strong-named assemblies, see Strong-Named Assemblies and How to: Sign an Assembly with a Strong Name.
The Strong Name tool is automatically installed with Visual Studio. To start the tool, use the Developer Command Prompt (or the Visual Studio Command Prompt in Windows 7). For more information, see Command Prompts.
[!NOTE]On 64-bit computers, run the 32-bit version of Sn.exe by using the Developer Command Prompt for Visual Studio and the 64-bit version by using the Visual Studio x64 Win64 Command Prompt.
At the command prompt, type the following:
Syntax
Parameters
Option | Description |
---|---|
-a identityKeyPairFile signaturePublicKeyFile | Generates xref:System.Reflection.AssemblySignatureKeyAttribute data to migrate the identity key to the signature key from a file. |
-ac identityPublicKeyFile identityKeyPairContainer signaturePublicKeyFile | Generates xref:System.Reflection.AssemblySignatureKeyAttribute data to migrate the identity key to the signature key from a key container. |
-c [csp] | Sets the default cryptographic service provider (CSP) to use for strong name signing. This setting applies to the entire computer. If you do not specify a CSP name, Sn.exe clears the current setting. |
-d container | Deletes the specified key container from the strong name CSP. |
-D assembly1 assembly2 | Verifies that two assemblies differ only by signature. This is often used as a check after an assembly has been re-signed with a different key pair. |
-e assembly outfile | Extracts the public key from assembly and stores it in outfile. |
-h | Displays command syntax and options for the tool. |
-i infile container | Installs the key pair from infile in the specified key container. The key container resides in the strong name CSP. |
-k [keysize] outfile | Generates a new xref:System.Security.Cryptography.RSACryptoServiceProvider key of the specified size and writes it to the specified file. Both a public and private key are written to the file. If you do not specify a key size, a 1,024-bit key is generated by default if you have the Microsoft enhanced cryptographic provider installed; otherwise, a 512-bit key is generated. The keysize parameter supports key lengths from 384 bits to 16,384 bits in increments of 8 bits if you have the Microsoft enhanced cryptographic provider installed. It supports key lengths from 384 bits to 512 bits in increments of 8 bits if you have the Microsoft base cryptographic provider installed. |
`-m [y | n]` |
-o infile [outfile] | Extracts the public key from the infile and stores it in a .csv file. A comma separates each byte of the public key. This format is useful for hard-coding references to keys as initialized arrays in source code. If you do not specify an outfile, this option places the output on the Clipboard. Note: This option does not verify that the input is only a public key. If the infile contains a key pair with a private key, the private key is also extracted. |
-p infile outfile [hashalg] | Extracts the public key from the key pair in infile and stores it in outfile, optionally using the RSA algorithm specified by hashalg. This public key can be used to delay-sign an assembly using the /delaysign+ and /keyfile options of the Assembly Linker (Al.exe). When an assembly is delay-signed, only the public key is set at compile time and space is reserved in the file for the signature to be added later, when the private key is known. |
-pc container outfile [hashalg] | Extracts the public key from the key pair in container and stores it in outfile. If you use the hashalg option, the RSA algorithm is used to extract the public key. |
`-Pb [y | n]` |
-q[uiet] | Specifies quiet mode; suppresses the display of success messages. |
-R[a] assembly infile | Re-signs a previously signed or delay-signed assembly with the key pair in infile. If -Ra is used, hashes are recomputed for all files in the assembly. |
-Rc[a] assembly container | Re-signs a previously signed or delay-signed assembly with the key pair in container. If -Rca is used, hashes are recomputed for all files in the assembly. |
-Rh assembly | Recomputes hashes for all files in the assembly. |
-t[p] infile | Displays the token for the public key stored in infile. The contents of infile must be a public key previously generated from a key pair file using -p. Do not use the -t[p] option to extract the token directly from a key pair file. Sn.exe computes the token by using a hash function from the public key. To save space, the common language runtime stores public key tokens in the manifest as part of a reference to another assembly when it records a dependency to an assembly that has a strong name. The -tp option displays the public key in addition to the token. If the xref:System.Reflection.AssemblySignatureKeyAttribute attribute has been applied to the assembly, the token is for the identity key, and the name of the hash algorithm and the identity key is displayed. Note that this option does not verify the assembly signature and should not be used to make trust decisions. This option only displays the raw public key token data. |
-T[p] assembly | Displays the public key token for assembly. The assembly must be the name of a file that contains an assembly manifest. Sn.exe computes the token by using a hash function from the public key. To save space, the runtime stores public key tokens in the manifest as part of a reference to another assembly when it records a dependency to an assembly that has a strong name. The -Tp option displays the public key in addition to the token. If the xref:System.Reflection.AssemblySignatureKeyAttribute attribute has been applied to the assembly, the token is for the identity key, and the name of the hash algorithm and the identity key is displayed. Note that this option does not verify the assembly signature and should not be used to make trust decisions. This option only displays the raw public key token data. |
-TS assembly infile | Test-signs the signed or partially signed assembly with the key pair in infile. |
-TSc assembly container | Test-signs the signed or partially signed assembly with the key pair in the key container container. |
-v assembly | Verifies the strong name in assembly, where assembly is the name of a file that contains an assembly manifest. |
-vf assembly | Verifies the strong name in assembly. Unlike the -v option, -vf forces verification even if it is disabled using the -Vr option. |
-Vk regfile.reg assembly [userlist] [infile] | Creates a registration entries (.reg) file you can use to register the specified assembly for verification skipping. The rules for assembly naming that apply to the -Vr option apply to –Vk as well. For information about the userlist and infile options, see the –Vr option. |
-Vl | Lists current settings for strong-name verification on this computer. |
-Vr assembly [userlist] [infile] | Registers assembly for verification skipping. Optionally, you can specify a comma-separated list of user names the skip verification should apply to. If you specify infile, verification remains enabled, but the public key in infile is used in verification operations. You can specify assembly in the form *, strongname to register all assemblies with the specified strong name. For strongname, specify the string of hexadecimal digits representing the tokenized form of the public key. See the -t and -T options to display the public key token. Caution: Use this option only during development. Adding an assembly to the skip verification list creates a security vulnerability. A malicious assembly could use the fully specified assembly name (assembly name, version, culture, and public key token) of the assembly added to the skip verification list to fake its identity. This would allow the malicious assembly to also skip verification. |
-Vu assembly | Unregisters assembly for verification skipping. The same rules for assembly naming that apply to -Vr apply to -Vu. |
-Vx | Removes all verification-skipping entries. |
-? | Displays command syntax and options for the tool. |
[!NOTE]All Sn.exe options are case-sensitive and must be typed exactly as shown to be recognized by the tool.
Remarks
The -R and –Rc options are useful with assemblies that have been delay-signed. In this scenario, only the public key has been set at compile time and signing is performed later, when the private key is known.
[!NOTE]For parameters (for example, –Vr) that write to protected resources such as the registry, run SN.exe as an administrator.
The Strong Name tool assumes that public/private key pairs are generated with the AT_SIGNATURE
algorithm identifier. Public/private key pairs generated with the AT_KEYEXCHANGE
algorithm generate an error.
Examples
The following command creates a new, random key pair and stores it in keyPair.snk
.
The following command stores the key in keyPair.snk
in the container MyContainer
in the strong name CSP.
The following command extracts the public key from keyPair.snk
and stores it in publicKey.snk
.
The following command displays the public key and the token for the public key contained in publicKey.snk
.
The following command verifies the assembly MyAsm.dll
.
The following command deletes MyContainer
from the default CSP.
See also
-->CLR Inside Out
Using Strong Name Signatures
Mike Downen
Contents
A Short Refresher
Strong-Name Signing
Why Use Strong Names?
What Strong Names Can’t Do
Working with Strong Names
Delay Signing
Test Key Signing
Managing the Private Key
Working with Authenticode
Strong name signatures (and signing in general) are a key facet of Microsoft® .NET Framework security. But regardless of how well designed .NET signatures may be, they won’t offer the maximum benefit if you don’t know how to use them properly. This installment of CLR Inside Out talks about strong names, strong name signatures, and how to use them.
A Short Refresher
Digital signatures are used to verify the integrity of data being passed from the originator (the signer) to a recipient (the verifier). The signatures are generated and verified using public key cryptography. The signer of a message has a pair of cryptographic keys: a public key, which everyone in the world knows, and a private key, which is kept secret by the signer. The verifier knows only the public key, which is used to verify that the signer knew the private key and the message.
In some cases, when some additional infrastructure is in place, digital signatures can also be used to reliably learn the name of the signer, and to ensure some chunk of data (a message, some code, or so on) has not been modified after the signer created the signature for the data.
Various mechanisms are used to implement digital signatures. The current implementation of strong names in the .NET Framework relies on the RSA public key algorithm and the SHA-1 hash algorithm.
Strong-Name Signing
Strong names offer a powerful mechanism for giving .NET Framework assemblies unique identities. The strong name for an assembly consists of five parts: a public key, a simple name, a version, an optional culture, and an optional processor architecture. The public key is an RSA public key. The simple name is just a text string—usually the name of the file (without the extension) that contains the assembly. The version is a four-part version number, in the form of Major.Minor.Build.Revision (for example, 1.0.0.1).
To get a valid strong name, an assembly is strong-name signed during the build process. This is done using the private key that corresponds to the public key in the strong name. The strong name signature can then be verified using the public key. There are a few different techniques for creating a strong name signature and for managing the private key used in signing. I’ll discuss these various techniques later in the column.
When one assembly references a strong-named assembly, the referring assembly captures the strong name information for the referenced assembly. When the .NET Framework loads a strong-named assembly, it verifies the strong name signature. If the strong name signature of the assembly cannot be verified, the .NET Framework will not load the assembly.
One exception to this process has to do with strong-named assemblies that come from the Global Assembly Cache (GAC). These are not verified each time the .NET Framework loads them. This is because assemblies in the GAC are verified when installed in the GAC. Since the GAC is a locked-down, admin-only store, assemblies located here do not need to be verified each time they are loaded.
Why Use Strong Names?
Strong names prevent spoofing of your code by a third party (that is, of course, as long as you keep the private key secure). As mentioned, the .NET Framework verifies the signature either when loading the assembly or when installing it in the GAC. Without access to the private key, a malicious user cannot modify your code and successfully re-sign it.
Given that strong names prevent spoofing, they can be used to make certain security decisions. An enterprise, for example, could choose to trust all code that comes from the enterprise’s intranet and has been signed with the enterprise’s strong name key. But strong name signatures do not contain any reliable information about the publisher, so while it is safe to trust keys you control, it is dicier to trust keys from other organizations unless you have a secure channel to get their public key.
It is also important to note that strong names do not have any revocation mechanism that can be used if the private key is compromised. It goes without saying that if you plan to use your enterprise’s strong name for trust, keep the private key private! (I’ll have tips for this later in the column.) It’s a good idea to scope the trust of a strong name to a particular location (such as your enterprise’s application server) or at least a zone (such as your intranet zone). This provides some mitigation in case your private key is ever compromised or a buggy version of a signed assembly makes its way to some bad guys and they try to lure users into running it from outside the intranet.
What Strong Names Can’t Do
Strong-name signing is useful for preventing a malicious user from tampering with an assembly and then re-signing it with the original signer’s key. It cannot do anything, however, to prevent a malicious user from stripping the strong name signature entirely, modifying the assembly, re-signing it with his own key, and then passing off the assembly as his own code. Digital signatures in general and strong name signatures in particular cannot help with this problem. Watermarking is a more appropriate solution for protecting against this scenario.
Strong names are secure only when the strong name private key is kept secure. As I mentioned earlier, they have no revocation capabilities and they don’t expire. Nor do strong names inherently provide any way to securely map a public key to a particular publisher. Thus, strong names should be used very cautiously when making security decisions. Ideally, these security decisions should only be made when you can be sure the strong name public key corresponds to a particular publisher (for example, when the public keys are generated by your organization’s IT department). You should note that more sophisticated signing schemes (for example, Authenticode®) are available that do offer revocation and publisher verification capabilities.
Working with Strong Names
Strong-name signing is a good idea for most applications, especially those that are deployed over a network or any medium not fully controlled by the deployer. The anti-spoofing and anti-tampering benefits are quite valuable. Arcgis 10.5 key generator. However, there are some challenges to be aware of when using strong-name signing.
First, all assemblies referenced by a strong-named assembly must also be strong-named. If you reference an assembly written by a third party that is not strong-name signed, you cannot strong-name sign your assembly.
Second, strong-name signing makes servicing more complicated. Under current versioning policy, an assembly will always attempt to load the exact version of the assembly it was built against. If, for example, your application was built against version 1.0.0.0 of a strong-named assembly and you fix a bug in the assembly, bumping the version number to 1.0.0.1, the existing application will not find the updated assembly.
There are a few ways to deal with this situation. You can rebuild the application against the new assembly. Obviously, this is an annoying process for just picking up a bug fix and it may not be an option in some situations. Still, it works fine when your code is not widely deployed or the assembly being serviced is not widely shared across applications.
Another option is if the assembly is installed in the GAC, you can use publisher policy to redirect loads for version 1.0.0.0 to version 1.0.0.1. However, publisher policy is complicated.
Yet another option is to fix the bug and not change the assembly version number, so existing applications can still find the assembly. This is the approach the .NET Framework uses for bug fixes, although it’s not appropriate for new features or anything that breaks compatibility. If you are adding new features, you should bump the assembly version up and have applications rebuild to opt in to the new features.
Needless to say, strong-name signing adds some complexity to your development and build processes. But this is necessary to keep the private key secure. I’ll discuss how to deal with this complexity in a moment.
Now let’s take a quick look at a simple signing scenario: creating a random key pair and storing it in a file. I’m only using this particular approach as a way to introduce you to how strong-name signing works. Obviously, storing the private key in a file next to your code is not a good way to protect your key so you generally should not use this approach in production.
If you are using command-line tools, you can create a key pair with sn.exe in the SDK. Then you pass that key pair to the compiler when compiling your code. The following commands create a new random key pair using sn.exe and build a strong-name signed assembly with csc.exe:
This produces a strong-name signed application named myapp.exe. You can do the same thing with Visual Studio® 2005. The Signing pane on the project properties page controls strong-name signing for your project (see Figure 1). To create a simple key file, select the 'Sign the assembly' option, and create a new key file that is not password protected. Visual Studio will add the key file to your project and use it to sign your application.
Figure 1** Signing the Assembly **
As I mentioned, storing the private key in a file next to your code is not a secure way to protect your private key. Fortunately, Visual Studio allows you to password-protect the key file. When you create a new strong name key for your project, just leave the 'Protect my key file with a password' option selected and enter a password for your key file (see Figure 2). Visual Studio adds a personal certificate, a PFX file, to your project. This file includes your encrypted private key, protected by the password you selected.
Figure 2** Creating a Key **
While password-protecting your key files is a much better solution than storing them in the clear, it is still not ideal. You would still have to distribute the PFX file to all of your developers, and they would all have to know the password for the PFX file. Secrets that are widely shared like this do not tend to stay secret for very long. Ideally, you should not have to distribute the private key to build and test your code during development.
Delay Signing
This is where delay signing enters the picture. Delay signing allows you to generate a partial signature during development with access only to the public key. The private key can be stored securely out of the hands of the developers and used to apply the final strong name signature just before shipping your code.
To use delay signing, follow these steps:
- Extract the public key from the key pair. The public key can be distributed to developers in your organization without any security risk.
- Use the public key to delay sign your assemblies during development. Because the assemblies are not fully signed yet, you’ll also have to configure your development machines to skip strong name signature verification for your key—otherwise, the .NET Framework will not allow you to load the delay-signed assemblies.
- When you are ready to ship your code, use the (well guarded) private key to apply the final strong name signature to your delay-signed assemblies.
For step one, you can use the sn.exe tool to extract the public key from a key pair. For example, say you have your key pair stored in a securely configured key container named EnterpriseKey on a locked-down machine. You would use the following command to extract the public key to the EnterprisePublicKey.pk file:
You can then distribute EnterprisePublicKey.pk to the developers in your organization. You can usually use the same public key for multiple assemblies because each will have a different simple name.
For step two, you use compiler options to delay sign your assemblies with the public key when building them. The example that follows creates a delay-signed application using options for the C# compiler:
Now if you try to run myapp.exe, it will not run because it does not have a valid full strong name signature. You must configure the .NET Framework to skip verification for the delay-signed assemblies using your public key. To do this, you use the sn.exe tool again. The following example configures the .NET Framework to skip strong name signature verification for the myapp.exe assembly on your development machines:
You can also use the sn.exe tool to skip signature verification for all assemblies signed with a particular key. For example, if you want to configure your machine to skip all assemblies delay signed with the same key as your application, you first do the following on your development machines:
This prints out the value of the public key token, a shortened version of the public key that looks something like this:
(Note that the actual value of the public key token will vary depending on your public key.) You then execute the following command to skip strong name verification for any assembly using that public key token:
Any assembly delay signed with that public key will now skip strong name signature verification and run on your development machine. Note that skipping strong name signature verification is something that should only be done on development machines. It should never be done on production computers because it opens up those machines to assembly spoofing attacks.
Finally, for step three, you use the real private key to generate the final full strong name signature before shipping your code. Again, you use the sn.exe tool to do this. For example, if your key pair is stored in a key container named EnterpriseKey on your signing computer, you would use the following command to sign a delay-signed assembly:
Now the assembly has a full signature. One of the nice things about delay signing is that it does not require any of the assemblies that use the delay-signed assembly to be rebuilt. Any assemblies that refer to the delay-signed assembly had access to its public key and were therefore able to create a full assembly reference, even though the assembly did not have a full signature.
Test Key Signing
There is a new feature in the .NET Framework 2.0 called test key signing. This is similar to delay signing. With test key signing, you sign your assembly with an alternate private key during development and then configure your development computers to verify the signatures against the alternate public key that corresponds to the alternate private key. Test key signing is valuable when you want almost the exact same behavior as full signing for testing purposes. For example, with delay signing, assemblies are not verified at all. This could hide performance issues if your application loads many strong-named assemblies because none of the strong name signatures would be verified during test runs when delay signing is turned on.
Test key signing involves the following steps:
- Delay sign your assembly.
- Create a test key pair with which to sign your assemblies. You can do this using sn.exe with the -k option.
- Test sign your assembly. You can do this using sn.exe and either the -TS or -TSc option. This will generate a signature for the assembly using the private key from your test key pair.
- Configure your development machines to use the test public key to verify the test key signed assemblies. You can use the –Vr option on sn.exe to do this.
When you are ready to ship your assemblies, you sign them with the real private key using sn.exe with either the -R or -Rc option, just as you would for a delay-signed assembly. The following series of commands creates a test key pair, test key signs a delay-signed assembly, extracts the test public key, and configures a development machine to verify the assembly against the test key:
When using test key signing, you should still protect the test private key, but you do not have to guard it as closely as the real private key. It is also a good idea to change the test key pair periodically.
Managing the Private Key
It is much easier to keep your private key secure if you are using delay signing or test key signing. You only have to have the private key installed on one or possibly a small number of locked-down signing computers. You can install the private key in a key container using restrictive access control lists (ACLs) to prevent unauthorized access to the key container. Alternatively, you can store the private key on a smart card or other separate hardware device. The sn.exe tool allows you to use a different cryptographic service provider (CSP) for signing. Take a look at the –c option in the documentation for sn.exe.
Working with Authenticode
Authenticode signatures provide more security semantics than strong name signatures. To generate an Authenticode signature, you have to obtain a code-signing certificate from a trusted certificate authority (CA). This can either be a commercial CA or a CA established by your IT department. The CA provides some level of assurance that the person or organization with the certificate is who they say they are, giving you some confidence that the software really came from the publisher listed in the signature. Authenticode also supports expiration and revocation, making it more flexible than strong name signatures. However, like strong name signatures, the presence of an Authenticode signature does not guarantee that you can trust the code. Authenticode simply provides some assurance about who published the code and that the code has not been tampered with since the publisher signed it.
Authenticode signatures can co-exist with strong name signatures. However, you must strong-name sign your assembly first, before applying the Authenticode signature. Adding the Authenticode signature will not invalidate a strong name signature.
Authenticode signatures can be used to trust applications deployed using the new ClickOnce model in the .NET Framework 2.0. You can use the tools in Visual Studio 2005 or in the SDK to apply an Authenticode signature to the deployment manifest of your ClickOnce application. You then install the certificate used to create the Authenticode signature in the trusted publisher certificate store on the client computers that will run your application; this can be done using Group Policy, Systems Management Server (SMS), or any other deployment mechanism available to you. Any ClickOnce application signed with this Authenticode certificate will run without any prompting. This is a convenient way to trust your enterprise’s applications.
Strong name signatures serve a valuable role in providing a form of identity for managed assemblies. Just remember that private key security is critical for strong names. If you do decide strong name signatures are appropriate for your organization, be sure to use some of the techniques discussed in this column to manage and protect the security of your private key.
Sn Exe Generate Key Pair Free
Send your questions and comments to clrinout@microsoft.com.
Sn Exe Generate Key Pair Key
Mike Downen is the program manager for security on the CLR team. He works on Code Access Security, the cryptography classes, and the ClickOnce security model. You can read Mike’s blog and contact him at blogs.msdn.com/CLRSecurity.