When to use Public/Private Key & when to gen new one?

G

Guest

Hello:
I'm trying to make sense of snk files, when to use, under what conditions to
regenerate new ones,...can someone take a look if these statemes make sense?
And then the final questions at the end that they first statements bring up
in my mind...


a) Because two developers, unbeknownst to each other, can end up releaseing
different dll's with the same name, one should sign an assembly with a unique
tag. right?

b) The key is generated by clicking (in VS2005) Properties/Signing and check
the checkbox. In VS2003 or prior, had to use first something like:
sn -k sn1.snk and wire that one into the assembly...

c) Although its main purpose in that case is just to create a uniqueness,
and a GUID would have done just fine, it's a public/private key thing rather
than a simple GUID for security purposes, so that another company can't
spoof it? In other words, that if you deliver a dll called
"ChaseManhattan.OpenSesame" that someone else can't pretend to be that same
dll, by building a rogue version of it, and embed the guid?

d) Public/Private. If I just let VS2005 handle the signing by the checkbox
process, I get one snk file -- what's the private part? what's the public
part? And what am I suppossed to do with the private part? Store it?

e) In other words, should I think of the private part as some kind of
certificate, and save it, and use the same private key for all sn
generations, for different assemblies? Or each assembly gets its own
private/public pair, and that's that?

f) And most importantly, atleast to me (in my ongoing struggle trying to
figure out how best to use Activator.CreateInstance (string) but remain as
flexible as possible... Do I keep the same snk file and its public/private
keys the same for all versions of the same assembly? In other words
(MyAssembly ver 1.0 and MyAssembly ver 14.0) get the same snk file? Or do I
regenerate a new one for each version? And just change the {version="..."}
part of the strong name when I am trying to get a System.Type from a fully
qualified assembly name string?

g) I have several assemblies that are built to run on desktop as well as on
CE. Same code, bar some #if and #else statements, different *.proj files (to
handle different references to CE or desktop versions of assemblies, etc.).
But they output different assembly names:
XAct.MyAssembly.dll
XActCE.MyAssembly.dll

My question is -- different names...can they use the same snk file in both?
I mean, different names, same version, same snk, would mean different
Assembly FQN's...right? So is it to do that? Or am I missing a point here?

Thank you very very much for helping making this all clear...finally !

Sky
 
N

Nicholas Paldino [.NET/C# MVP]

Sky,

See inline:
a) Because two developers, unbeknownst to each other, can end up
releaseing
different dll's with the same name, one should sign an assembly with a
unique
tag. right?

Well, that depends on whether or not strong naming is important to you.
Personally, I would strong name anything that I publish. However, it only
becomes an issue if you have to set a reference to both of these assemblies.

It's not even that much of an issue with the ability to set references
to the same-named assembly.
b) The key is generated by clicking (in VS2005) Properties/Signing and
check
the checkbox. In VS2003 or prior, had to use first something like:
sn -k sn1.snk and wire that one into the assembly...
Yep.

c) Although its main purpose in that case is just to create a uniqueness,
and a GUID would have done just fine, it's a public/private key thing
rather
than a simple GUID for security purposes, so that another company can't
spoof it? In other words, that if you deliver a dll called
"ChaseManhattan.OpenSesame" that someone else can't pretend to be that
same
dll, by building a rogue version of it, and embed the guid?

The Guid has nothing to do with the strong name of the assembly. The
reason for the public and private part of the key is for trust purposes.
Assuming you keep the private part of your key safe (and people trust that
you can keep it safe), they can make a trust decision that anything signed
with that private key is trustworthy.
d) Public/Private. If I just let VS2005 handle the signing by the checkbox
process, I get one snk file -- what's the private part? what's the public
part? And what am I suppossed to do with the private part? Store it?

They are both in the .snk file. I believe you can use the sn.exe tool
to split them into two separate files, if you wish, but that's up to you.

And yes, you need to store it. This is the weakest link in the chain,
really.
e) In other words, should I think of the private part as some kind of
certificate, and save it, and use the same private key for all sn
generations, for different assemblies? Or each assembly gets its own
private/public pair, and that's that?

You could give each assembly a public/private pair, that's up to you.
Personally, I wouldn't want to give a public/private pair to each assembly,
only because in larger solutions, that can be tedious.

I would go so far as to say that one strong name key for one company is
fine. Maybe one for each unique application. However, if you have
components that are shared across applications, then you have to worry about
which signature to sign it with.
f) And most importantly, atleast to me (in my ongoing struggle trying to
figure out how best to use Activator.CreateInstance (string) but remain as
flexible as possible... Do I keep the same snk file and its public/private
keys the same for all versions of the same assembly? In other words
(MyAssembly ver 1.0 and MyAssembly ver 14.0) get the same snk file? Or do
I
regenerate a new one for each version? And just change the {version="..."}
part of the strong name when I am trying to get a System.Type from a fully
qualified assembly name string?

I would definitely use the same strong name for the versions. Your
assembly name is going to change based on the version alone, why complicate
it with the strong name?

If, based on the previous answer, you are using one strong name per
application, then you might want to consider using a new strong name for
major version changes in the product.

However, even that can be tedious, which is why I think one strong name
per company is better.
g) I have several assemblies that are built to run on desktop as well as
on
CE. Same code, bar some #if and #else statements, different *.proj files
(to
handle different references to CE or desktop versions of assemblies,
etc.).
But they output different assembly names:
XAct.MyAssembly.dll
XActCE.MyAssembly.dll

My question is -- different names...can they use the same snk file in
both?
I mean, different names, same version, same snk, would mean different
Assembly FQN's...right? So is it to do that? Or am I missing a point here?

Yes, you can use the same SNK file for signing both. Of course the
Assembly FQN is going to be different, even if you use the same SNK file.
Why? Because the names of the assemblies are different (XAct.MyAssembly.dll
vs XActCE.MyAssembly.dll).

Hope this helps.
 
G

Guest

Just want to dot the i's here a second.

Verification:
The key pair is uniquely bound to each other: you can't have one private key
work with another public key, right?
So my question about using one *private* key per company is a red herring --
its actually using one *private/public keypair* per company, (if that's what
we wanted).
I'm guessing this because in the command line arguments of sn.exe I see
options for extracting the public key, but not one for 'build new public key
for this assembly, given the following private key'...which is mabe more an
Authenticode kind of thinking, not what this signing is about. Point is: one
private key=>one public key. That's it.

b) Embed the public key only?
Looking at the command line arguments for sn.exe I see:
sn -k sn1.snk Generates and stores the key pair in the file 'sn1.snk'.
sn -p sn1.snk snpub1.snk Extracts the public key from the key pair file
'snk1.snk' and stores the public key in the file 'snpub1.snk'.
Up to this point, I was including in assemblies whatever it had spat one
(either manually with VS2003, now automatically with VS2005) -- which was a
combo private/public key file.
Should I have been *not* embedding this full private/public one, but gone
through a second stage of extracting only the public key, and embedding that
*public* one only, keeping the full private/public sn1.snk file in a safe
place?

b)
Or...does the compiler actually do all that -- extract the public key and
use only that -- and there is no reason to do this by hand as there is no
means to spoof/worry about in the first place.

d) But if it doesn't, would going over older assemblies where I did do this,
and going through the process of exporting a public key from each in order to
re-embed only the public key (sn1_public.snk), and storing the public/private
snk file, would that change the signature? Or ok to do so? I should think
that this would cause no difference, since its the public one that the FQN is
computed from... What do you think?

d) As for what to use: I like simplicity too (when possible :) ): maybe a
good compromise is to have two snk files: one for apps, one for library stuff
that can cross apps?
Then again, what is the argument against using a different one for each
assembly? It's not as if it has any specificity other than uniqueness in it
anyway, right?

e) And I think this ends up answering my question of the other day wondering
if Public Key Tokens change across different builds/releases: since MS will
probably keep the same snk file across various builds of an assembly, as you
suggested would be a better practice, and because I found out that the Public
Key Token is created by (i) Generate hash of this public key using SHA1
algorithm.
ii) Extract the last 8-byte sequence of the SHA1 hash of the public key.
iii) Reverse the 8-byte sequence) that it therefore will remain constant
across builds, so Assembly FQN's will only change by version number... good.
Or atleast better... still wish I could get it to be more flexible than it is
.... I'm concerned that if I make a reference to a GAC assembly (eg:
System.Configuration.dll version 2.0) that it immediately break on a future
OS where they may have Framework 4.0 (since 3.0 is 2.0 + special effects),
but don't have 2.0 installed....see where I'm going with all this?

Anyway. It appears to be (slowly!) all coming together in my head...thanks
for your patience, and tips, Nicholas!





Nicholas Paldino said:
Sky,

See inline:
a) Because two developers, unbeknownst to each other, can end up
releaseing
different dll's with the same name, one should sign an assembly with a
unique
tag. right?

Well, that depends on whether or not strong naming is important to you.
Personally, I would strong name anything that I publish. However, it only
becomes an issue if you have to set a reference to both of these assemblies.

It's not even that much of an issue with the ability to set references
to the same-named assembly.
b) The key is generated by clicking (in VS2005) Properties/Signing and
check
the checkbox. In VS2003 or prior, had to use first something like:
sn -k sn1.snk and wire that one into the assembly...
Yep.

c) Although its main purpose in that case is just to create a uniqueness,
and a GUID would have done just fine, it's a public/private key thing
rather
than a simple GUID for security purposes, so that another company can't
spoof it? In other words, that if you deliver a dll called
"ChaseManhattan.OpenSesame" that someone else can't pretend to be that
same
dll, by building a rogue version of it, and embed the guid?

The Guid has nothing to do with the strong name of the assembly. The
reason for the public and private part of the key is for trust purposes.
Assuming you keep the private part of your key safe (and people trust that
you can keep it safe), they can make a trust decision that anything signed
with that private key is trustworthy.
d) Public/Private. If I just let VS2005 handle the signing by the checkbox
process, I get one snk file -- what's the private part? what's the public
part? And what am I suppossed to do with the private part? Store it?

They are both in the .snk file. I believe you can use the sn.exe tool
to split them into two separate files, if you wish, but that's up to you.

And yes, you need to store it. This is the weakest link in the chain,
really.
e) In other words, should I think of the private part as some kind of
certificate, and save it, and use the same private key for all sn
generations, for different assemblies? Or each assembly gets its own
private/public pair, and that's that?

You could give each assembly a public/private pair, that's up to you.
Personally, I wouldn't want to give a public/private pair to each assembly,
only because in larger solutions, that can be tedious.

I would go so far as to say that one strong name key for one company is
fine. Maybe one for each unique application. However, if you have
components that are shared across applications, then you have to worry about
which signature to sign it with.
f) And most importantly, atleast to me (in my ongoing struggle trying to
figure out how best to use Activator.CreateInstance (string) but remain as
flexible as possible... Do I keep the same snk file and its public/private
keys the same for all versions of the same assembly? In other words
(MyAssembly ver 1.0 and MyAssembly ver 14.0) get the same snk file? Or do
I
regenerate a new one for each version? And just change the {version="..."}
part of the strong name when I am trying to get a System.Type from a fully
qualified assembly name string?

I would definitely use the same strong name for the versions. Your
assembly name is going to change based on the version alone, why complicate
it with the strong name?

If, based on the previous answer, you are using one strong name per
application, then you might want to consider using a new strong name for
major version changes in the product.

However, even that can be tedious, which is why I think one strong name
per company is better.
g) I have several assemblies that are built to run on desktop as well as
on
CE. Same code, bar some #if and #else statements, different *.proj files
(to
handle different references to CE or desktop versions of assemblies,
etc.).
But they output different assembly names:
XAct.MyAssembly.dll
XActCE.MyAssembly.dll

My question is -- different names...can they use the same snk file in
both?
I mean, different names, same version, same snk, would mean different
Assembly FQN's...right? So is it to do that? Or am I missing a point here?

Yes, you can use the same SNK file for signing both. Of course the
Assembly FQN is going to be different, even if you use the same SNK file.
Why? Because the names of the assemblies are different (XAct.MyAssembly.dll
vs XActCE.MyAssembly.dll).

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)
Thank you very very much for helping making this all clear...finally !

Sky
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top