Why do i have a wrong (sha1) immediate startcom certificate in my chain on azure website? - azure

My immediate certificate on https://paper-shape.com got a weak signature algorithm SHA1: https://www.ssllabs.com/ssltest/analyze.html?d=paper-shape.com
I followed theses instructions. I created my pfx file both per OpenSSL and per certificate export wizard.
The CRT and pem (immediate certificate from startcom) seem to be ok, because the following command shows "Signature Algorithm: sha256WithRSAEncryption" on both (CRT and PEM):
$ openssl x509 -text -in paper-shape.com.crt
Either something went wrong during my pfx creation process or azure website overrules my immediate certificate.
Has anybody an idea?

Check your locally-installed certificates (on Windows, 'certmgr.msc'). You may have an old SHA-1-signed copy of the StartCom intermediate certificate which is still valid (say, to 2017) and being used in preference to that provided by the server.

You can find (and chain) the SHA-256 intermediate certificate for Class-1 in PEM format, here: https://www.startssl.com/certs/class1/sha2/pem/sub.class1.server.sha2.ca.pem

I have been facing this same problem, I was about to pull my hair out when the certificate seemed to be right in some browsers and OS and in others it claimed I was using SHA-1 and even https://shaaaaaaaaaaaaa.com was telling me that I had a SHA-2 signed crt.
So! Here is a huge thread in StartCom forum about this issue: https://forum.startcom.org/viewtopic.php?f=15&t=15929&st=0&sk=t&sd=a
The thing is that the browser is using an Intermediate crt that is SHA-1 signed.
The solution: you need to configurate the Intermadiate crt in your server!
You can see more details here:
https://sslmate.com/blog/post/chrome_cached_sha1_chains

Related

Cross-platform code-signing of .tar.gz file using OpenSSL?

I'm adding automatic upgrades to an application of mine. I need code-signing for this, or else automatic upgrades could be an attack vector. I need the signing and verification to be doable with "openssl" commands, since my application can run on any platform, and OpenSSL is available on any platform. However, when I try to verify a timestamp with openssl, with the code-signing certificate I bought from Comodo, I get the error "Verify error:unable to get local issuer certificate". The commands I run are as follows:
First, I extract the private key and the certificates from the .p12 file from Comodo, with the following:
openssl pkcs12 -in full-certs-from-comodo.p12 -nocerts -out private-key.pem
openssl pkcs12 -in full-certs-from-comodo.p12 -nokeys -out certs.pem
Then, to query and verify a timestamp, I run:
openssl ts -query -data mydata.tar.gz -cert -CAfile certs.pem -sha256 -out request-256.tsq
cat request-256.tsq | curl -s -S --data-binary #- -H 'Content-Type: application/timestamp-query' 'http://timestamp.comodoca.com?td=sha256' > response-256.tsr
openssl ts -verify -sha256 -in response-256.tsr -data mydata.tar.gz -CAfile certs.pem
This is the full error that results:
Verification: FAILED
140710242829968:error:2F06D064:time stamp routines:TS_VERIFY_CERT:certificate verify error:ts_rsp_verify.c:246:Verify error:unable to get local issuer certificate
Comodo tech support can't solve it, and I've been communicating with them for a month now. Digicert says they can only sign certain kinds of files, and those don't include a .tar.gz file. *sigh*
I've never used code-signing before, but that doesn't sound right to me, unless Digicert is adding artificial restrictions. Can't I hash any file, sign the hash with a private key, and then verify it on the user end with the public key? I don't think it should be this hard. What don't I understand?
Anyway, I'd love to get this working even with a paid certificate vendor, but failing that I'm wondering if I can just create my own key pair (a la PGP) and use that. I guess I wouldn't be able to revoke the certificate; are there any other downsides? In particular, does anyone see any reduced security by doing it this way? I do need very good security for this app.
The application is a Perl script and normally runs on a Web server, i.e. usually a *nix platform, but can also run on Windows.
Thanks! I appreciate any clues in getting this working at all, in any way, paid or not. I can't be the first person to need this kind of code-signing, but Comodo and Digicert tech support seemingly haven't heard of it at all.
Maybe not an answer but definitely too much for comments.
Aside: OpenSSL is available on many platforms, but not all. Although you only care about platforms where your app can be installed, and perl is already pretty demanding of platforms and can't be installed anywhere near everywhere.
More Important: code-signing and trusted timestamping are different and separate things, although sometimes used together: some codesigning schemes like Microsoft and Java encourage (but don't require) you to get a trusted timestamp on the (code) signature; I'm not sure about Apple, or Android. In particular you can't (validly) use a code-signing cert for timestamping, or verifying timestamps, and if you can get a timestamping cert (you probably can't meet the requirements to be trusted by anyone besides yourself, see below) you can't use it for signing or verifying code. Although the error you got on ts is probably not because of this misuse but because you did something else wrong, but you don't tell us what you did, and imagining and describing the very many things you could possibly have done wrong would take far more than is justified for or even fits in a single Stack answer.
The cert can't restrict what you can sign, but it may restrict where that signature will be trusted. In particular for Microsoft Authenticode, only a cert from a CA specifically approved by Microsoft will work. And I believe Apple only trusts certs they themselves issue.
Yes, if you control both/all ends you don't need a 'real' cert; the (only) value of a trusted-thirdparty CA, and certs from it, is allowing your system(s) and/or code to trust data or code from those of other people, and/or other people's to trust yours, under known and more or less reasonable conditions. You presumably trust yourself entirely, unless you're Michael Garibaldi. If you use OpenSSL's 'primitive' signing functions (commandline dgst -sign/verify or rsautl/pkeyutl -sign/verify, or the equivalent library calls) you only need the two keys, private and public. If you use CMS (aka PKCS7) or S/MIME signatures you need a cert, but it can be a self-signed cert with any identity information, true or false, you feel like putting in it.

How to use an SSL certificate from wosign in node.js

I'm trying to use a free ssl certificate(s?) I got from wosign in node.js, but I'm having some issues.
I'm creating my server with:
var server = https.createServer({key: serviceKey, cert: certificate}, httpHandler).listen(port)
which works fine with my self-signed certificate. To allow wosign to generate a certificate, I gave them the CSR that was generated alongside my self-signed certificate. They gave me the following files:
root.crt
3_user_my.domain.crt
2_issuer_Intermediate.crt
1_cross_Intermediate.crt
I've also read through the following couple sources to help me along:
https://www.ohling.org/blog/2015/02/wosign-free-2y-ssl-certificate.html
http://www.lowendtalk.com/discussion/41289/free-chinese-2-year-ssl-certificate-dv-kuaissl-by-wosign-com
Both mention that the "order" of the certificates is important, but I don't know what they mean there. I assumed that there would be a single certificate I could replace my self-signed certificate with. If there's an order, I assume it goes 1->2->3 as those numbers are in the filenames.
I replaced my certificate with the 3_user_my.domain.crt contents, and it works like my self-signed one - chrome says it should only work on localhost.
So how do I "order" these certs and ultimately how do I use the files given to me so that browsers will recognize it correctly?
Ok, I got it working.
A. I learned that the "certificate" used actually can be multiple certificates (crt files that only have one -----BEGIN CERTIFICATE----- and one -----END CERTIFICATE-----. So in order to make it work right, I needed to create one certificate file/string that contained 3 of the 4 certificates I got in the right order (apparently the root.crt isn't useful)
B1. The English set of certificate wosign gave me didn't match my private key, which I verified using the following:
openssl x509 -noout -modulus -in yourcertificate.crt | openssl md5
openssl rsa -noout -modulus -in private.key | openssl md5
# If both outputs match, the cert matches the key, otherwise they don't
B2. So I chose the chinese certificate option, and there was a much different set of certs in the archive I got from that. I used the bundled cert for NGINX. And that works!

IIS TLS Certificate - Chrome says we are using "obsolete cryptography"

We have installed a server certificate in IIS for a website. When browsing over HTTPS to the website and inspecting the icon using chrome, we get a message "Your connection ... is encrypted with obsolete cryptography".
How do I configure IIS so that Chrome stops displaying this message, also need to balance the need to support IE>=8.
[EDIT]: As per the screenshot, we can see that the encryption method used is "AES_256_CBC with SHA1 for message authentication". The question is how do we change this in IIS so that Chrome no longer complains about "Obselete Cryptography".
The answer Steffen gave is incorrect (although the link he provided does provide the answer if you read further down). The reason Chrome gives the error regarding obsolete cryptography in this case is due to AES in CBC mode.
It has nothing to do with having a SHA-1 certificate.
The TL;DR - ignore this error, it doesn't matter.
If you really want to get rid of the error then you need to enable AES GCM instead. However this is easier said than done. I answered this in full on serverfault recently - see the second half of my answer here;
https://serverfault.com/questions/683697/change-key-exchange-mechanism-in-iis-8/683705#683705
Since am new to SSL and certificates, I struggled with this too. Here's how we solved this issue. Note that in our case, we are working with an internal web application and use a self-signed certificate.
Using OpenSSL on Linux, create a private key:
openssl genrsa -out box.key 2048
Then create and sign a certificate with the key (we set the expire date for a year out and 10 days):
openssl req -new -x509 -sha256 -days 375 -key box.key -out box.crt
Answer the questions (make sure the Common Name matches the web server's FQDN)
Configure your web server to use SSL using this key and certificate
Using Chrome on Windows, enter your web sites HTTPS URL
Click on the lock icon in the address bar, then select the Certificate Information link in the popup
Go to the Details tab, select the Copy to File... button to launch the Certificate Export Wizard
Using the wizard, select PKCS #7 as the export format, and save the certificate (i.e. mykey.p7b)
Install the certificate in the Trusted Root Certification Authorities certificate store (use certmgr.msc or right click on the certificate and select Install Certificate
Close Chrome, logout and re-login to Windows (force the old site warning out of the cache)
Re-open Chrome and enter your web sites HTTPS URL
Admire your shiny green lock icon with modern cryptography
You might want to read https://www.chromium.org/Home/chromium-security/education/tls#TOC-Deprecation-of-TLS-Features-Algorithms-in-Chrome, which was the first hit when looking for this specific error message.
It is hard to know for sure without having a look at your certificate, but I guess the following description from the linked page will match your certificate:
SHA-1 is deprecated in Chrome at the start of 2015.
Certificates expiring in 2016 will be marked as "secure, but with minor errors".
Certificates expiring in 2017 are later will be treated as "affirmatively insecure".
To answer my own question:
Ensure latest Windows Updates have been installed
Download and run IIS Crypto (https://www.nartac.com/Products/IISCrypto)
Ensure that this Cipher is top of the list on the left hand side:
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
Apply changes in IIS Crypto
Restart the server
In this link there are a black and a white lists about ciphers. Maybe if you just use the white ones it would solve your problem. Look after the lists in the comments you will see that it has change a little since the answer was written.
It helped me a lot when I started to have this problem with Glassfish, I hope it helps you with IIS too.

Setting https on expressjs PEM routines:PEM_read_bio:no start line

A few similar threads exist but none has a checked answer or much discussion. I'm trying to setup an https server on express js but I'm getting
crypto.js:100
c.context.setKey(options.key);
^
Error: error:0906D06C:PEM routines:PEM_read_bio:no start line
I generated my .csr and .key files with
openssl req -nodes -newkey rsa:2048 -keyout myserver.key -out myserver.csr
One suggestion was to convert the .csr to a .pem by following these instructions: http://silas.sewell.org/blog/2010/06/03/node-js-https-ssl-server-example/
That didn't work.
The express.js docs (http://nodejs.org/api/https.html) show both of these files as .pem, however. If that's the issue, how would you convert a .key file to a .pem? This threat is partially helpful How to get .pem file from .key and .crt files? but if anyone knows what expressjs requires, I feel that's the missing component.
How would I check that the files are properly in ANSI, or convert them if not?
There is also some discussion on whether the file should begin with -----BEGIN ENCRYPTED PRIVATE KEY----- or -----BEGIN RSA PRIVATE KEY-----
Any help is greatly appreciated.
So i think there's at least a little bit of terminological confusion, and the node.js example you have there doesn't help by renaming everything to .pem.
Here's a general overview for how SSL works:
You generate a pair of public and private keys. For our purposes the former is your "certificate signing request" (CSR for short) and the latter is your private signing key (just "your key").
If you wanted to generate a self-signed certificate (this is useful for local testing purposes) you can turn around and use your key and your CSR to generate a certificate. This link http://www.akadia.com/services/ssh_test_certificate.html has a pretty clear run down of how to do that on a *nix based system.
For the purposes of web browsers, SSL certificates need to be co-signed by a trusted authority, e.g. a Certificate Authority (CA). You pay a CA to co-sign your cert, and vouch for your authenticity with browser vendors (who will in turn display a green padlock for your site when your website presents its certificate to browsers).
The co-signing process starts with you uploading your CSR to your CA. They will then take that CSR and generate your certificate. They will then provide you with a couple of certificates, your certificate, their root certificate, and possibly some intermediate certificates.
You then need to form a combined certificate that proves a chain of authenticity back to browsers. You do this literally just by concatenating your certificate, followed by the intermediate certificates (in whatever order was specified) ending with the root certificate. This combined certificate is what you hand to your web server.
In order to enable your web server to serve over SSL, you need to hand it your (combined) certificate as its public encryption key (which it provides to web browsers upon request), and your private encryption key, so that it can decrypt the traffic sent to it by web browsers.
So. Now with all of that in mind, you should take that CSR that you have and provide it to your CA, and get the various certificates back, concatenate them, and then use that w/ your private key in your express server.

Determining if a TLS/SSL certificate is 'trusted' from the command line?

I would like to be able to determine if a remote domain's TLS/SSL certificate is 'trusted' from the command line.
Here is an openssl example I was playing with a few weeks back, here I use openssl to acquire the certificate and then pipe it to openssl's 'verify' command. I assumed that the 'verify' command would verify the certificate, however, how I understand it now is that the 'verify' command just verifies the certificate chain (I think). (cdn.pubnub.com is just a domain I found from a quick Twitter search as an example to use)
echo "GET /" | openssl s_client -connect cdn.pubnub.com:443 | openssl x509 -text | openssl verify
As you can see from the cdn.pubnub.com domain (at the time of writing), the browser (Chrome at least) does not trust the certificate (because the certificate domain doesn't match), however, the openssl 'verify' command does not output 'trusted' or 'not trusted' or something else we can deduct that information from.
Another way I thought of doing this, is by using a headless browser (such as PhantomJS) and parsing any errors they return. It turns out that PhantomJS just errors but does not give any details, so this can not be used as the error could have been caused by something else.
I didn't think it would be this hard to find out that a certificate was trusted or not from the command line, without having to parse and check all the data that makes a certificate trusted myself which I don't think would be wise.
Is there a library or some other way I can tell if a remote domain's certificate is trusted from the command line?
curl (and libcurl) uses OpenSSL for https URLs, and checks certificate validity unless -k, --insecure option is enabled.
zsh 29354 % curl https://cdn.pubnub.com/
curl: (51) SSL peer certificate or SSH remote key was not OK
As you see, it doesn't give much details on why the certificate is invalid, but otherwise it should be as good as a headless browser, and much lighter.
It depends on what you consider "trusted". Beside the core cryptographic checks (e.g. checking the digital signature) the client usually does the following:
Check that the certificate chains to a trusted root
Verify that the current time is between the notValidBefore and not validAfter attributes.
The certificate is not revoked.
keyUsage and other certificate constraints match.
The entity we are communicating is somehow found in the subject of the certificate (for servers this usually means the hostname is listed as CN or subjectAlternativeName).
In your case the information to verify step 5 (namely the hostname) is missing, so it cannot be checked. You would have to do this step yourself.
Please note that different clients perform different checks to see if a certificate is trusted, so one answer may not apply to all possible clients. If you want to check your installation deeply, consider using the check from ssl labs https://www.ssllabs.com/ssltest /

Resources