I seem to have gotten hung up now on an issue of what "encoding
method" is used to take the hash of the certificate and convert it to
the form that's stored in the CertificateHash registry value. I've
been banging away at my code for a while but I haven't determined this
by accident; now I'm hoping someone will be able to help me figure
this out. Eventually this'll allow me to act on the CertificateHash
registry value as a String, which is *not* possible now.
As stored in the certificate's Thumbprint field, my current
CertificateHash value is 68 66 de ba 6b 0c 5b fe 75 d0 af 6e f9 f1 3c
b9 23 ba 50 d8. This is what I see in Regedit.exe, but when I
actually try to edit the value (to copy it out), it looks more like
this: hf.[pn#<_ [plus a bunch of characters that I can't easily type
here]
Anyone have any clues here? Is this certificate hash an MD5 hash of
the entire DER-encoded certificate? Is it SHA-1? Is it MD5 or SHA-1
of just the public key in the cert? And most importantly, how would I
take the output of an MD5 hashing function and convert it to something
I can use to compare to what I've already got?
Thanks all, Mike
You probably mean
HKEY_CURRENT_USER\Software\Microsoft\Windows
NT\CurrentVersion\EFS\CurrentKeys\CertificateHash
According to
http://technet2.microsoft.com/windowsserver/en/library/04122595-5d30-4b19-945a-b6e4bb33bd6f1033.mspx?mfr=true
this registry key contains he certificate hash used by the current user to
encrypt and decrypt data.
As for the algorithm I think it is SHA-1 (on mine Win XP SP2 system) and I think
it is SHA-1 hash of the certificate encoded in DER format. (Please somebody
correct me if I'm wrong).
You can verify it this way. Export the certificate using DER encoding and use
Hash Calc (http://www.slavasoft.com/hashcalc/index.htm) or fciv
(http://support.microsoft.com/kb/841290) to compare the hash to value that is
stored in registry.
As for the bunch of characters this is because CertificateHash is a binary value.
If you want to modify the registry, you can create a registry file like this
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\EFS\CurrentKeys]
"CertificateHash"=hex:HERE_GOES_COMMA_SEPARATED_HASH_VALUES
for example
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\EFS\CurrentKeys]
"Flag"=dword:00000002
"CertificateHash"=hex:e5,a9,8d,96,3b,16,3a,ab,ce,e8,e7,26,ac,6a,30,2c,47,71,91,8c
Any comments appreciated.
Regards
Martin
I've talked this over with a couple of smarter folks at work, and
realized that I was over-complicating the problem.
There's a nice little .Net method X509Certificate2.GetCertHashString()
that lets me retrieve a cert's hash (aka "Thumbprint") as a String
data type.
e.g. C480C669C22270BACD51E65C6AC28596DFF93D0D
I'm using a different method to retrieve the value of the
CertificateHash registry setting - because it's a REG_BINARY, it seems
I have to retrieve it as a byte array. i.e.
_certificateHashRegistryValue =
(byte[])_registrySubKey.GetValue(valueName, null);
I'd like to compare the _certificateHashRegistryValue with the
Thumbprint above. Unfortunately, I'm pretty dopey about this and I
cannot for the life of me figure out how to make the conversion in my
code, so that I can make a reasonable comparison.
Anyone have any clues that could help me out?
Thanks, Mike
On Aug 1, 5:04 am, Martin Rublik <martin.rub...@nospam.com> wrote:
> Hi
>
> You probably mean
> HKEY_CURRENT_USER\Software\Microsoft\Windows
> NT\CurrentVersion\EFS\CurrentKeys\CertificateHash
>
> According tohttp://technet2.microsoft.com/windowsserver/en/library/04122595-5d30-...
the hash string is byte representation (in hexadecimal) of the hash so you can
either concatenate the byte array in hex representation as a string and compare
them or you can use .Net method X509Certificate.GetCertHash() which will return
a byte array.
I have a question too. According to documentetion
(http://msdn2.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509certificate.getcerthash.aspx)
X509Certificate.GetCertHash Method returns the hash value for the X.509v3
certificate as an array of bytes. I coudln't find any documentation on the hash
algorithm used. I suppose it is SHA-1 but I can't find it in documentation.
Thanks - I'm glad to hear I wasn't insane trying to attack the
concatenation problem. However, I have run out of ideas on how to
actually perform the concatenation you describe as "concatenate the
byte array in hex representation as a string". I would've figured
there'd be a nice class already available for this, but not that I can
find.
I've also tried techniques like what was outlined here, but I couldn't
figure out how to get it to display the cert hash in a form like
"C480C669C22270BACD51E65C6AC28596DFF93D0D":
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1656747&SiteId=1
Any ideas folks?
Martin, as to your question of which hash algorithm is used, I ended
up reminding myself of a basic detail I'd long forgotten... If you
open a digital certificate in Windows and explore the Details tab,
you'll find one of the Fields labelled "Thumbprint algorithm". That
indicates that it depends on the cert issuer to determine which
hashing algorithm to use. [I presume the X.509 RFCs specify allowed
algorithms, but I haven't looked recently enough.] All the Windows-
issued certs I've got all seem to use SHA-1 - it's possible that's the
only supported hash algorithm on Windows to date, though I have to
imagine that Microsoft will *finally* catch up to reality by Windows
7.
The property SignatureAlgorithm.FriendlyName of the X509Certificate2
class could be useful to you.
[And yes, I know - I slapped my forehead pretty hard when I noticed
this too.]
On Aug 2, 12:08 am, Martin Rublik <martin.rub...@nospam.com> wrote:
> Hi,
>
> the hash string is byte representation (in hexadecimal) of the hash so you can
> either concatenate the byte array in hex representation as a string and compare
> them or you can use .Net method X509Certificate.GetCertHash() which will return
> a byte array.
>
> I have a question too. According to documentetion
> (http://msdn2.microsoft.com/en-us/library/system.security.cryptography...)
I'm not very sure about this.
Although RFC 2459 and X.509 defines the certificate structure,
Certificate ::= SEQUENCE {
tbsCertificate TBSCertificate,
signatureAlgorithm AlgorithmIdentifier,
signatureValue BIT STRING }
TBSCertificate ::= SEQUENCE {
version [0] EXPLICIT Version DEFAULT v1,
serialNumber CertificateSerialNumber,
signature AlgorithmIdentifier,
issuer Name,
validity Validity,
subject Name,
subjectPublicKeyInfo SubjectPublicKeyInfo,
issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
-- If present, version shall be v2 or v3
subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
-- If present, version shall be v2 or v3
extensions [3] EXPLICIT Extensions OPTIONAL
-- If present, version shall be v3
}
the signatureAlgorithm only specifies which algorithm should be used to verify
the signature of the issuing CA (signatureValue).
However the hash you get from registry is a hash from the *whole* certificate
(meaning the tbsCertificate,signatureAlgorithm and signatureValue) so it is up
to you whether you use the same hash as specified in signatureAlgorithm or not.
For example take an md5RSA AlgorithmIdentifier signed certificate. (If you don't
have one you can find one here
http://www.win.tue.nl/hashclash/TargetCollidingCertificates/), Open it and
you'll see again Thumbprint algoritm SHA-1, thumbprint ...
And again, any comments appreciated.