I am trying to understand the key high level details behind verifying trust when downloading an archive.
This is my understanding of how it could be done:
On the Software Developer side:
Obtain a certificate from a public CA like verisign
Generate a hash of your archive and then encrypt this string using the private key from your certificate, this is the "signature"
Host the archive for download, along with a separate file which contains the public key from your certificate + the signature generated in step 2.
On the (user) client side:
Download and unpack the archive, download the signature + public key file
Decrypt the downloaded signature using the downloaded public key, save this value
Iterate through the public root certificates embedded within your operating system. For each root certificate, decrypt the signature value and compare the result to the result in step 5.
Once a match is found in 6, you have verified that the author's private key descends from the chain of trust of the CA which you found matched in step 6.
This all assumes that the software developer used a CA for which we have an embedded root certificate in our clients OS.
Questions:
Is the above method sound, or am I overlooking key details?
Given a blank slate client that you control, if I wanted to combine the public key + signature + archive into a single file that I could make the client understand and parse, are there any widely supported formats to leverage for organizing this data?
Aside from being a little too specific on Developer (2) (that describes how RSA signatures work, but ECDSA is perfectly well suited to this task) that sounds rather like Authenticode minus some EKU restrictions. This leads me to ask "why not use Authenticode signing?".
The structure I'd consider is the PKCS#7/CMS SignedData format. It can describe multiple signatures from multiple certificates (sign it ECDSA-brainpoolP320t1-SHA-3-512 for anyone who can read it as well as RSA-2048-SHA-2-256 for most of us, and DSA-1024-SHA-1 for anyone whose computer was built in 2001).
For data file you can just use SignedData normally, for executables it's harder since there are semantic portions (so you have to squirrel it away somewhere and use indirect signing).
If you do your signing with .NET, PKCS#7/CMS SignedData is available for both signing and verifying via System.Security.Cryptography.Pkcs.SignedCms (though you probably have to define your own chain trust rules outside of that class).
Related
I've done a fair bit of reading about digital signatures but I can't for the life of me work out why I'd need to verify the signature of a digitally signed file uploaded on a mirror site.
The question popped up when I tried to install Maven:
https://maven.apache.org/download.cgi
The site urges you to "verify the signature of the release bundles against the public KEYS used by the Apache Maven developers".
I understand the need for integrity which a checksum provides (granted MD5 is considered weak) - why do I need to do more? I know the file that I've downloaded has not been modified since the checksum was initially generated.
Digital signatures are supposed to provide integrity, authenticity and non-repudiation.
1) Integrity is already provided anyway by confirming the checksum.
2) Authenticity - verifies identity of signer. In this case, the signer is the owner of the public key (supposedly a maven developer). In this scenario, do I really care who signed the file?
3) Non-repudiation - Do I really care that the developer can't deny the file was signed by him/her? Maybe if the maven developer created a malicious file and I wanted to sue them for distributing it...
I don't see the significance of authenticity here. I KNOW the sender (eg. someMirrorSite.com) is not the one who signed the file since if I use their public key to try verify the signature, it would be invalid. If I use the maven developer's public key all I'm verifying is the fact that the maven developer signed the file (granted they have a valid certificate which links that maven developer with their public key).
So basically the question is: Provided that I trust maven.apache.org, why should I verify the signature of the file hosted by the mirror site when I can just simply verify the checksum of the file?
Is basically a perspective, do I care who made or compiled a file? Who is behind this so called signed document/file/byte array?
Behind a signed file is Private Key Infrastructure, is like having a notarized document when a particular risky transaction is on play and a bunch of lawyers around, why should I care? Well it depends how important that activity is for you or a third party. Let's say You want to sell a company (small business). This is risky, may be not for you but for the third party, he will make sure there is a notary present to witness the transaction and the state he is receiving the company. At this point it becomes clear to you that you also need a notarized document of you selling the company. Who knows what's going to happen next? May be you don't care what happns next, as long as it's sold, so no notarized document (aka digitally signed document).
Check Integrity = Just lawyers
Digitally Signed Document = You don't trust lawyers that much so you need a notary (who is basically a lawyer anyway :-))
If there is a file F, and C = checksum(F), then when you download F you can recompute C and see if it matches the published value. But, how do you know if this published value of C can be trusted? If I am "Evil Inc." I can make a compromised copy of F, call it Fe and then compute its checksum Ce, and publish both on my website. Many people will not bother to even look at the checksum, but even those that do will be fooled, because they will compute Ce too.
Using a Public Key signature as the checksum is an attempt to strengthen this procedure.
I've created and signed a new executable file (the file is signed with double signature SHA1 and SHA256 and timestamped).
Since 1/1/2016 if I try to download it from Internet Explorer (or Microsoft Edge) I get an error (saying the signature is corrupted).
Smartscreen also tells that the file is not signed.
If I look at the file from the properties, it has the two signatures.
Can you help me out understanding what's the problem?
Here's the link for the download PhraseExpander setup file
Thanks.
This is what I wrote here:
valid certificate is corrupt with IE
I still doesn't have a solution, because I am not able to request a SHA-2 certificate. But you can't download any application from web with a SHA-1 certificate, anymore.
Class 3 certificates are a step above the Class 2. Class 2 does not require “Extended Validation”. However the “EV” code signing certificates combine all of the regular benefits of digitally-signed code with a rigorous extended validation process. They represent the gold standard for authentication and security in code signing certificates. EV code signing certificates adhere to strict validation standards from the CA/Browser Forum and to Microsoft specifications. Enhanced authentication is provided via an encrypted token containing the private key.
im 100% new to digital signature, as far as i understand, a document is signed by an user private key, and that signature is checked using the public key. my problem is that i have a web application, and a file server... Files are created on an earlier stage. then an user that is using the application checks the files and signs them using his key.
those files are stored on a file server and they need to be strip from some of the content in order to do the signature (according to the implementation manual of the file, an HL7 CDA file). so, i need some direction to understand how to do this, should i retrieve the file, then alter it and sign it from the browser, or should i send the private key to the server and make all things there?
or any other option, mks.
There are three options possible:
Transfer the file to the client. Have some client-side module that performs signing. The difficulty is that the files can be huge.
Transfer the key to the server. Sign the data on the server. This can be a problem if the private key is non-exportable (stored in hardware or just flagged as non-exportable in Windows CryptoAPI).
Use the distributeed solution which will calculate the hash on the server, transfer it to the client, calculate the signature on the client and send it back to the server. The example of such solution can be found in this SO answer.
I am implementing an auto-update mechanism for my software. The msi on the server is signed using signtool. My app downloads the msi and reads the public key of the downloaded msi. If the public key matches the one that is hard coded in the source code, it will execute the msi and update itself.
Would this is be sufficient to ensure that no malicious msi gets executed by mistake? My understanding is that a file will have the same public key ONLY if signed by my certificate.
Edit:
With petey's help, I was able to detect if the msi was signed by my certificate or not. However, this didnt quite solve my problem. I can still edit the signed msi using a tool like Orca. Even the msi is no longer the same as the one that was signed, nothing happens to certificate. So when I check whether the msi is signed by me, I get yes. While I understand that this might be intended behaviour, but there must be some way to detect if the msi was tampered with??
Odds are, if it's the same public key, yes it is the same certificate. But with this knowledge an attacker could easily mimic your public key and stick it on his MSI, because, well it's public. You should use that public key to verify the signature on the MSI, not just check if it's the same public key, that way you would be certain it was signed with your corresponding private key, which no attacker would have. You should also run up the cert chain and verify signatures right up to your trusted CA.
Edit:
What exactly are you signing? A signature should not be valid if what was signed is altered. However, it sounds like a Message Authentication Code (keyed hash) would work. If you have a pre-shared hashing key, you could hash the MSI before it is downloaded, then verify the hash again client side. Or if you dont want to use a keyed hash, you could use a regular hash then sign the hash value with that same private key. If you can "verify" (ie decrypt) the hash with the public key, you know that hash came from you, then you can re-hash the msi and check if the hashes are the same.
Question for all the SSL experts out there:
We have an embedded device with a little web server on it, and we can install our own SSL self-signed certificates on it. The client is written in .NET (but that doesn't matter so much).
How can I authenticate the device in .NET? Is it enough to compare the fingerprint of the certificate against a known entry in the database?
My understanding is that the fingerprint is a hash of the whole certificate, including the public key. A device faking to be my device could of course send the same public certificate, but it couldn't know the private key, right?
Or do I have to build up my own chain of trust, create my own CA root certificate, sign the web server certificate and install that on the client?
What you propose is in principle ok. It is for example used during key signing parties. Here the participants usually just exchange their name and fingerprints of their public keys and make sure that the person at the party really is who he/she claims. Just verifying fingerprints is much easier than to verify a long public key.
Another example is the so called self certifying file system. Here again only hashes of public keys get exchanged over a secure channel. (I.e. these hashes are embedded in URLs.) In this scheme the public keys don't have to be sent securely. The receiver only has to check that the hash of the public keys matche the hashes embedded in the URLs. Of course the receiver also has to make sure that these URLs come from a trusted source.
This scheme and what you propose are simpler than using a CA. But there is a disadvantage. You have to make sure that your database with hashes is authentic. If your database is large then this will likeley be difficult. If you use CAs then you only have to ensure that the root keys are authentic. This usually simplifies the key management significantly and is of course one reason, why CA based schemes are more popular than e.g. the self certifying file system mentioned above.
In the same way you wouldn't and shouldn't consider two objects to be equal just because their hash codes matched, you shouldn't consider a certificate to be authentic just because its fingerprint appears in a list of "known certificate fingerprints".
Collisions are a fact of life with hash algorithms, even good ones, and you should guard against the possibility that a motivated attacker could craft a rogue certificate with a matching fingerprint hash. The only way to guard against that is to check the validity of the certificate itself, i.e. check the chain of trust as you're implying in your last statement.
Short:
Well in theory you then do exactly what a Certificate Authority does for you. So it should be fine.
Longer:
When a Certificate Authority signs your public-key/certificate/certificate request it doesn't sign the whole certificate data. But just the calculated hash value of the whole certificate data.
This keeps the signature small.
When you don't want to establish your own CA or use a commercial/free one -
by comparing the fingerprint with the one you trust you'll gain the second most trustworthy configuration. The most trustworthy solution would be by comparing the whole certificate, because also protects you from hash collision attacks.
As the other guys here stated you should make sure to use a secure/safe hashing algorithm. SHA-1 is no longer secure.
more detailed informations to this topic:
https://security.stackexchange.com/questions/6737
https://security.stackexchange.com/questions/14330