Category Archives: Security

My response, to his response, to my response? or short-lived certificates part 3

The conversation on short-lived certificates and their value continuesIn the most recent conversation, we have started to shift from an either or position to one where we explore what is needed to make revocation checking a viable technology, this is a topic I am passionate about.

That said, there still seems to be some confusion on short-lived certificates, specifically the author states:

Of course, the cost of short-lived certs is very high as change the whole computing infrastructure so that certificates are renewed on a daily basis (daily for it to be secure enough vs 90 day certificates in my view) and introduce this new moving part that might cause vulnerability and operational issues.

Let’s explore this “cost” argument for a moment. First, when I issue an end-entity certificate I minimally have to perform two cryptographic signatures, one on the certificate and one on the OCSP response (it’s actually more than this in some cases but to keep the conversation simple I have omitted the others).

If we look at the performance optimization that Firefox has implemented where they do not require revocation checking when the certificate is within a subset the resolution of the revocation period short-lived certificates can, in fact, reduce the cost for a CA. This is because you no longer need to sign two things during the first few days/hours of the life of the certificate and you do not need to distribute that response.

The only way I think short lived certificates are more expensive for the CA is if you compare a model of certificates issued for a period better measured in hours to a model with certificate validity measured in years providing weekly revocation updates. This, however, is a bad model, and something in-between is needed.

The author also believes the use of automation represents a security vulnerability, so this deserves a response. It is true that complexity is the enemy of security, it is even true that automation can if poorly implemented can hurt security. The inverse is also true, however.  It is also generally accepted that availability is a component of security and one of the more common problems in the WebPKI is poor manual management practices resulting in the lack of understanding what is deployed and those certificates that are deployed expiring [see 1,2,3, and 4] and taking down services.

It is also important to look at the big picture when evaluating the net-security benefits of automation, for example, does anyone honestly believe we would ever get to a world where the majority of the web is encrypted if organizations have to staff people to manually generate certificate requests and hand carry them to CAs? Is the net-benefit of automation of reliability and scope of deployment worth its secondary effects?

The author also suggests that a certificate must have a validity period of only a day to be “secure enough”. This seems both arbitrary and wrong, as stated previously the User Agents and WebTrust allows an OCSP response or CRL can be a week old and still be trusted.

One of the largest reasons for this is that clock skew is a big problem in the real world and as a result, you need to keep validity periods of certificates and revocation messages outside this skew period to prevent skew related failures.

The decision to define “secure enough” at a day, both defines the problem in an intractable way and furthermore ignores the fact that it establishes a double standard that does nothing to address the issue if stale revocation information.

If we were to bring this conversation back to how we improve certificate revocation I would say there should be one standard for how recent the client’s understanding of the certificate’s validity would need to be.

On that topic, the author goes on to discuss how 32 bytes is better than 470 (the size of the smallest OCSP response). I could not agree more about this, in fact in the 90s’ when I was at Valicert we implemented a proposal from Paul Kocher called Certificate Revocation Trees. This approach uses of Merkle Trees (the heart of the Bitcoin ledger) to provide a very space efficient solution to this problem. Unfortunately, we were unable to popularize this at the time.

Ben Laurie began work on a variation on this approach that leveraged sparse Merkle Trees that he called Revocation Transparency. I personally like the idea of this approach because it leverages the work done to make Certificate Transparency scalable. For example, Trillian, the foundational server for Google’s next generation log server is designed to scale to Trillions of certificates.

That said, there are a number of similar approaches that could be equally scalable.

While I do think that an approach similar to the above could be made to work today, I also think it is more of a long-term solution in that even with the significantly increased rate of technological adoption it would take close to ten years given the state of things for such a solution to be fully deployed if we started right now.

As such I would start with the problem definition, which would need to involve a more formal analysis of the role of revocation checking today so that the right solution was built.

In parallel I would want to see the industry adopt a more strategic plan to address the more practical and immediately solvable problems, including:

  • Measuring and improving the revocation infrastructure operated by CAs,
  • Establishing global performance and reliability metrics and reporting that all CAs must meet,
  • Funding improvements to Nginx and Apache’s OCSP Stapling implementations,
  • Working with browsers to adopt the performance optimization firefox has implemented for revocation checking,
  • Working with TLS stacks, User Agents, Servers and Service Providers to adopt OCSP Must-Staple,
  • Defining an OCSP transport based on DNS that would reduce dependency on CA infrastructure reliability,
  • Evangalizing the adoption of OCSP stapling with administrators.

Ryan

P.S.

The author also has also added in someone else who has asked some questions or more correctly seems to question my version of the historical narrative. To provide some context, my narrative comes from my practical experience working with Microsoft, eBay, Amazon, and other large companies in the mid to late 90s and through the mid-2000s.

I too have worked with the BBN Safekeeper, I have a fun story how we hired some people to extract the keys from one of these boxes I would be happy to share over a beer sometime.

However, a cool device, the first one I remember working with was the KOV-8 in the 1993/4 timeframe.

Anyway, it is true that SSL started its life in 1994/5 at which point only software implementations of crypto were used (they were all BSAFE) but it is also true that mass deployment of SSL (relatively speaking) did not start until the late 90s and early 00s and that is the time my narrative was based on.

He also has also questioned the narrative of what Windows supported in the context of key protection. Since the author knows me personally he must have simply forgotten that I was the PM for these technologies and was at Microsoft working in this area for about 15 years.

Again I think there is some confusion here, the author states:

The software based Cryptographic Service Provider for RSA allowed keys to be marked ‘not for export’ from a very early release if not the first.

and:

The CAPI features used to protect private keys were expanded and exposed as a separate API in Windows 2000 as the Data Protection API.

As someone who worked at Microsoft on these technologies for a long time I can say with absolute confidence they were not built to provide key isolation, do not provide key isolation properties and were actually not used by the SSL implementation (SCHANNEL) for the server keys. If you’re interested in learning more about the capabilities of Windows in this area check out this post I did recently.

He has also questioned the role of ValiCert in the definition of the RFC, thankfully the IETF PKIX archives are still there and if you care to look you can see Mike was basically checked out, Warwick was not publicly paticipating and the work to finalize the protocol was largely done by Ambarish Malpani the founder of Valicert.

It is my turn, or short-lived certificates part 2

My response to a recent post suggesting short-lived certificates were intended to remove the need to do revocation seems to have spurred a response from its author.

The thesis of the latest response is that:

Revocation can easily handle “key compromise” situation and do so by offering more security than short-lived certs.

The largest problem with this thesis is that it is based on an incorrect understanding. That being the author believes short-lived certificates do not get checked for revocation, or they believe it is a choice between short-lived certificates and revocation.

Both statements are not true. User Agents do not say “oh, this certification is short-lived so we won’t do revocation checking”. If User Agents do revocation checking of end-entity certificates, and not all do, the short-lived certificate will get checked just like the long-lived certificate.

Now there is a reasonable argument to be made that if CAs are allowed to produce revocation lists and OCSP responses every 7 days, and User agents will trust them for that time, that it wouldn’t be an unreasonable performance optimization. At least if the behavior was limited to certificates with validity periods shorter than 7 days. With that said, User Agents don’t do this today and I didn’t suggest they should in my post.

[Update 10:43PM May 4th 2017 It seems a changed happened while I was asleep at the wheel. Firefox has implemented the below optimization as of Firefox 41. A corrected statement follows in the next  two paragraphs]

Both statements are not true, well except for one performance optimization implemented by Firefox I will explain shortly. Basically, if User Agents do revocation checking of end-entity certificates, and not all do, the short-lived certificate will get checked just like the long-lived certificate as long as it is younger than the corresponding CRL or OCSP response would be (Firefox only).

This performance optimization Firefox implemented is based on the fact that  CAs are allowed to rely on 7-day old OCSP responses and CRLS. As a result, 7 days becomes the precision of revocation checking, It is not clear what value Firefox chose but it is a subset of that figure, not 90 days. But either way, no major CA that I am aware of issues such short-lived certs today due to time skew issues.

The second problem with this thesis is it presumes the user who does know of a compromise wants to announce it to the world and can. As I mentioned in an earlier post on revocation reasons subscribers are not keen to announce to the world that there was “a compromise”. I mention “can” because in some cases the one who knows about the comromise do not even have sufficient permissions to the associated CA consoles to request the revocation.

And finally, the last issue in this thesis is that it presumes an effectiveness of revocation checking. Today over 9% of OCSP responses fail due to issues with the CA’s revocation infrastructure (the connections time out).

That’s right 9 out of 100 revocation checks fail because CAs fail to operate capable enough infrastructure to meet the needs of the clients that rely on them. It is actually worse than that though, the largest websites use a technique called Domain Sharding to make their sites load faster, this means that the failure rate you would experience as a user if hard-fail was implemented could be 2-4x higher than that.

This is before we consider the fact that due to the poor performance and failures in CA revocation infrastructure revocation checking has been largely turned off in Chrome and other browsers.

I say this because for “revocation checking” to work for a key compromise case you need two things:

  • The CA to know the compromise occurred,
  • Revocation checking to actually work.

Now I want to be clear, I think revocation checking is a good thing and I would like to see the situation improved, as a proof of that statement here is an example of some of my work in this area:

  • While at ValiCert (the lead creators of OCSP) I worked on the standardization of RFC 2560 (OCSP) including running the interoperability testing that led to its ultimate standardization,
  • I also am the author of RFC 5019 which is the profile of OCSP in use by CAs and clients,
  • I have led the development of numerous PKI SDKs and servers which have implemented these standards (including leading the team that added support for OCSP to Windows),
  • I led the implementation of the first, and most reliable implementation of OCSP stapling (in SCHANNEL),
  • I led the CASC project to get OCSP stapling added Nginx,
  • I have helped create, and/or recreate numerous CAs and along with their revocation infrastructure,
  • And I led the first wide scale measurement and efforts of the CA revocation infrastructure via my X509LABS Revocation Report project which led to all CAs adopting the same design philosophies to begin to address abhorrent response times and uptime.

Basically, I see the value in revocation checking and think the investments need to be made to make it work and be relevant for the WebPKI of today. That said, this topic has zero to do with short-lived certificates.

Ryan

How to keep a secret in Windows

Protecting cryptographic keys is always a balancing act. For the keys to be useful they need to be readily accessible, recoverable and their use needs to be sufficiently performant so their use does not slow your application down. On the other hand, the more accessible and recoverable they are the less secure the keys are.

In Windows, we tried to build a number of systems to help with these problems, the most basic was the Window Data Protection API (DPAPI). It was our answer to the question: “What secret do I use to encrypt a secret”. It can be thought of as a policy or DRM system since as a practical matter it is largely a speed bump for privileged users who want access to the data it protects.

Over the years there have been many tools that leverage the user’s permissions to decrypt DPAPI protected data, one of the most recent was DPAPIPick. Even though I have framed this problem in the context of Windows, Here is a neat paper on this broad problem called “Playing hide and seek with stored keys”.

The next level of key protection offered by Windows is a policy mechanism called “non-exportable keys” this is primarily a consumer of DPAPI. Basically, when you generate the key you ask Windows to deny its export, as a result the key gets a flag set on it that can not, via the API, be changed. The key and this flag are then protected with DPAPI. Even though this is just a policy enforced with a DRM-like system it does serve its purpose, reducing the casual copying of keys.

Again over the years, there have been numerous tools that have leveraged the user’s permissions to access these keys, one of the more recent I remember was called Jailbreak (https://github.com/iSECPartners/jailbreak-Windows). There have also been a lot of wonderful walkthroughs of how these systems work, for example, this nice NCC Group presentation.

The problem with all of the above mechanisms is that they are largely designed to protect keys from their rightful user. In other words, even when these systems work they key usually ends up being loaded into memory in the clear where it is accessible to the user and their applications. This is important to understand since the large majority of applications that use cryptography in Windows do so in the context of the user.

A better solution to protecting keys from the user is putting them behind protocol specific APIs that “remote” the operation to a process in another user space. We would call this process isolation and the best example of this in Windows is SCHANNEL.

SCHANNEL is the TLS implementation in Windows, prior to Windows 2003 the keys used by SCHANNEL were loaded into the memory of the application calling it. In 2003 we moved the cryptographic operations into Local Security Authority Subsystem Service (LSAS) which is essentially RING 0 in Windows.

By moving the keys to this process we help protect, but don’t prevent, them from user mode processes but still enable applications to do TLS sessions. This comes at an expense, you now need to marshal data to and from user mode and LSAS which hurts performance.

[Nasko, a former SCHANNEL developer tells me he believes it was the syncronous nature of SSPI that hurt the perf the most, this is likely, but the net result is the same]

In fact, this change was cited as one of the major reasons IIS was so much slower than Apache for “real workloads” in Windows Server 2003. It is worth noting those of us involved in the decision to make this change surely felt vindicated when Heartbleed occurred.

This solution is not perfect either, again if you are in Ring 0 you can still access the cryptographic keys.

When you want to address this risk you would then remote the cryptographic operation to a dedicated system managed by a set of users that do not include the user. This could be TCP/IP remoted cryptographic service (like Microsoft KeyVault, or Google Cloud Key Manager) or maybe a Hardware Security Module (HSM) or smart card. This has all of the performance problems of basic process isolation but worse because the transition from the user mode to the protected service is even “further” or “bandwidth” constrained (smart cards often run at 115k BPS or slower).

In Windows, for TLS, this is accomplished through providers to CNG, CryptoAPI CSPs, and Smartcard minidrivers. These solutions are usually closed source and some of the security issues I have seen in them over the years are appalling but despite their failings, there is a lot of value in getting keys out of the user space and this is the most effective way of doing that.

These devices also provide, to varying degrees, protection from physical, timing and other more advanced attacks.

Well, that is my summary of the core key protection schemes available in Windows. Most operating systems have similar mechanisms, Windows just has superior documentation and has answers to each of these problems in “one logical place” vs from many different libraries from different authors.

Ryan

Why bother with short-lived certificates and keys in TLS?

There seems to be a lot of confusion and misinformation about the idea of short-lived certificates and keys so I thought I would pen some thoughts about the topic in the hope of providing some clarification.

I have seen some argue the rationale behind short-lived certificates is to address the shortcoming in the CA and browser revocation infrastructure, I would argue this is not the case at all.

In my mind, the main reason for them is to address the issue of key compromise. Long-lived keys have a long period in which they are exposed to theft (see Heartbleed) and therefor are a higher value to an attacker since a stolen key enables the attacker to impersonate the associated website for that period.

The most important thing to keep in mind is that the nature of key compromise is such that you almost never know it has happened until it is too late (consider Diginotar as an extreme example).

The importance of protecting the SSL private key is why in the 90s when SSL deployment started in earnest, large companies tried to deploy SSL in their environment using SSL “accelerators” and “security modules” that protected the keys. This was the “right technical” thing to do not not the right “practical thing” because it significantly reduced the scalability of SSL protected services and at the same time massively increased the cost to deploy SSL.

By the mid 00’s we recognized this was not workable and the use of accelerators basically stopped outside a few edge cases and software keys were used instead. Some implementations, like the Microsoft SCHANNEL implementation, tried to protect the keys by moving them to a separate process mitigating the risk of theft to some degree. Others simply loaded the keys into the web servers process and as a result exposed them to Heartbleed like attacks.

What’s important here is that when this shift happened no one pushed meaningful changes to the maximum validity period of certificates and by association their private keys. This meant that we had software keys exposed to theft for five years (max validity period at the time) with no reliable way to detect they were stolen and in the unlikely event we did find out of the theft we would rely on the unreliable CA revocation infrastructure to communicate that issue to User Agents — clearly this was not an ideal plan.

In short, by significantly reducing the validity of the certificate and keys, we also significantly reduce the value to the attacker.

Another issue that short-lived certificates help mitigate is the evolution of the WebPKI, with a long-lived certificate you get virtually no security benefits of policy and technology improvements until the old certificates and keys are expunged from the ecosystem. Today this is rollout of new policy largely accomplished via “natural expiration” which means you have to wait until the last certificate that was issued under the old policies expires before absolute enforcement is possible.

So what is the ideal certificate validity period then? I don’t think there is a one-size-fits-all answer to that question. The best I can offer is:

As short as possible but no shorter.

With some systems it is not possible to deploy automation and until it is one needs to pick a validity period that is short enough to mitigate the key compromise and policy risks I discussed while long enough to make management practical.

It is probably easier to answer the question what is the shortest validity period we can reliably use. The answer to that question is buried in the clock skew of the relying parties. Chrome recently released a new clock synchronization feature that significantly reduces errors related certificate validity periods. But until that is fully deployed and other UAs adopt similar solutions you are probably best to keep certificate validity periods at 30 days to accommodate skew and potential renewal failures.

In-short, long-lived keys for SSL exist because we never re-visited the threat model of key compromise when we stopped using hardware-protected keys in our SSL deployments and short-lived keys help deal with the modern reality of SSL deployments.

Ryan

– I have added a few pictures for fun and made some minor text changes for clarity.

Revocation reasons don’t make sense for the WebPKI of today

As the old saying goes, to err is human but to forgive is divine, in WebPKI you deal with errors through the concept of revocation.

In the event a CA determines it made a mistake in the issuance of a certificate or has been notified by the subscriber they would like to see a certificate marked invalid, they revoke the corresponding certificate.

The two mechanisms they have available to them to do this are called Certificate Revocation Lists and OCSP responses. The first is a like a phonebook of all known “revoked” certificates while the last is more like a lookup that it enables User Agents to ask the status of a particular set of certificates.

In both cases they have the option to indicate why the certificate was revoked, the available options include:

Reason Description
Key Compromise We believe the key to have been stolen or can no longer be sure it has not been.
CA Compromise The issuing CA itself has been compromised (think DigiNotar).
Affiliation Changed The certificate contained affiliation information, for example, it may have been an EV certificate and the associated business is no longer owned by the same entity.
Privilege Withdrawn The right to represent the given host was revoked for some reason.

There are a few other reasons but they are not materially relevant to WebPKI use cases so I left them out.

CA Compromise is clearly a special and exceptional case, so much so that browsers have developed their own mechanism for dealing with it (see OneCRL and CRLSets) so it’s not particularly relevant to the options available to CAs anymore, at least in the WebPKI.

Another thing to consider when looking at revocation reasons is that about 90% of all certificates in used in the WebPKI (for TLS) are considered to be Domain Validated (DV) certificates, this limits the applicability of the remaining reasons substantially.

DV OV EV
Key Compromise Yes Yes Yes
Affiliation Changed Maybe Yes Yes
Privilege Withdrawn Maybe Yes Yes


As you can see, the available “reasons” for DV certificates are largely reduced to just “Key Compromise”. There is an argument that both “Privilege Withdrawn” and “Affiliation Changed” could be applicable to DV but in my opinion, they are a bit of a stretch. If nothing else the difference between these two reasons in the case of DV is so subtle you will almost never see these two usages be used on a DV certificate.

So what about Key Compromise?  How useful is it? Clearly, it is an important use case, your trust in an SSL certificate is frankly only as good as your confidence in how well the key is protected!

The reality is that most key compromise cases can not be detected and worse yet is that it’s far too easy to compromise an SSL key. Take for example the Heartbleed (http://heartbleed.com/) bug from last year, SSL keys are often kept in the process and relatively minor coding mistakes, as a result, can potentially expose that key and users won’t necessarily know about it.

Some platforms go out of their way to prevent such attacks at the expense of performance like we did at Microsoft with SCHANNEL where we keept the key out of process but this is the exception and not the rule.

Also popping a web server due to some third-party code vulnerability and getting to the shell in the context of the server is unfortunately far too easy. As a result, when an attacker does get a shell on a web server one of the first things they should be doing is taking that key so they can use it later, but again, how is this detected?

That is not to say “Key Compromise” as a revocation reason is not important when there is a large-scale vulnerability like Hearbleed but this is not exactly a common case.

The other cases for the “Key Compromise” revocation reason are notably dependent on the subscriber:

  • Knowing the compromise happened,
  • Being mindful enough to notify the CA,
  • Being willing to let the world know there was a compromise.

This last point of public signaling of “compromise” combined with the fact user agents treat all revocations the same (if they check at all) means that we seldom see subscribers even specify a reason when they ask for a certificate to be revoked.

As I look at why a certificate gets revoked today I think there are a few cases, these include:

  • CA has decided the certificate should be revoked,
  • The subscriber has decided the certificate should be revoked,
  • A root program has decided a certificate should be revoked.

These are far more meaningful signals to relying parties that the ones listed above and are not so specific that these is any negative signaling in their use.

Today it is not possible to specify these things but maybe we should take a second look at revocation reasons and if we continue to use them make them more relevant to the way the WebPKI works today.

Ryan

Secondary effects when encrypting the web

Secondary effects

Effects are often classified as having primary and secondary impacts. As we evolve the Internet we can see numerous examples of secondary effects, this is especially true as we look at how we evolve the way we secure it.

To put this in perspective consider the amazing milestone we have just hit, as of 2017 over half of the web is encrypted. Browsers will now be able to gradually switch from showing the “lock” as an exceptional and positive indicator to showing an error when a session is not encrypted. In fact, Chrome has already started this transition and as soon as October 2017 we will start to see it rollout.

I can not overstate how huge a change this is. For the last 23 years, SSL has been the exception and not the norm, as a result the best we could do as software developers was throw site developers a few pixels (the lock) for going out of their way to encrypt their sites. Now, we can do what we always wanted, warn the user when there is something to be concerned about.

It took a lot to get us to this point, some of which included:

  • Competition driving the cost of a certificate from thousands of dollars to as little as $0,
  • Evolution and standardization of certificate formats and of the TLS protocol,
  • Maturation and improving performance of TLS implementations,
  • Increase in average computational power so the overhead was negligible,
  • The definition and evolution of standardized practices and audits for certificate authorities,
  • The definition and standardization of a certificate enrollment protocol suitable for TLS use cases,
  • Formalization of user agent root programs and criteria in which CAs are managed to,
  • Establishment of technologies to effectively monitor and manage the CA ecosystem,
  • Migration to SaaS and the Cloud services where management of deployments can be handled in a seamless way,
  • And of course, education tooling to help the operators deploy TLS correctly.

While we are not done with this journey we have made it a long way and the end is in sight.

Each of these changes had secondary effects, even if small, but let’s look at the meta change to get a better understanding of what the consequences of change on the TLS ecosystem were.

Nobody ever did, or ever will escape the consequences of his choices. – Alfred A. Montapert

One obvious one that immediately comes to mind is that we have a generation of non-technical people who believe “the lock means it is secure” when it never really meant that.

As they say, correlation is not the same as causation, I would argue this is the reason the “Lock” myth came to be. That is because in the beginning it literally did cost thousands of dollars to get an SSL certificate, and if you were committed enough to sign up for that there was a good chance you were a big company who was at least thinking about security. This was especially true because those companies were also typically existing brick and mortar companies with reputations to protect.

From this myth, evolved another belief, that being that phishers don’t use SSL. This was true in the beginning, there were a few reasons for this, of course, the cost was one but it was also cumbersome and phishing is a numbers game so if users don’t notice the lock then why bother?

A few things have changed, through education more users today are aware of encryption and absence of the “lock” means more today than it did then. Additionally, the process of getting a certificate has been reduced to a task that can literally take about a minute and then of course cost has reduced to the point it’s inconsequential.

These things basically invalidate the once true assumption that phishers don’t bother to use SSL. Now, thankfully after the creation of SSL, we got technologies like SafeBrowsing and SmartScreen which are actually designed for, and are effective at, addressing this issue. Also with the lock disappearing over the next few years the “credibility” boost of the SSL lock will go away diminishing that value to the phisher. But is this true for other secondary effects?

It is worth noting that another secondary effect we will surely see is confusion from users as this change roles out, even though it is unquestionably better to warn users when they are at risk.

Let’s look at a larger example of a secondary effect of the move to encryption, specifically I believe BGP is a good example. The other day Dan Goodin over at ARS did a great article on a potentially malicious BGP rerouting event. In this article, he talked about how the attacker could have used the Logjam or DROWN attacks to attempt an MITM and that is true, but it’s not the only way. It no longer takes hours to get a certificate, you can get Domain Validation (DV) SSL certificate from many different providers in a matter of minutes now, a decade ago, or even just five years ago that could have taken hours.

This is important because to get an SSL certificate all you have to do is prove you control the associated host and one of the ways you can do that is by dropping a file with a pre-shared value in it on the host. If you can get the network traffic redirected to you for seven minutes like happened in this BGP rerouting case you can also get an SSL certificate for a host in the associated network segments.

In the past, the cumbersome and slow process involved in getting an SSL certificate made that practically impossible, but today it is not. This means that the broad use of SSL has, as a secondary effect, pushed the attacker down a level to BGP as a means to achieve its goal.

As a result, we will surely see BGP get more attention from attackers and eventually shore up its security so it is not as susceptible to these rerouting attacks. I also wouldn’t be surprised if we see the WebPKI evolve to make it slightly harder for this sort of attack to take place (by prohibiting certain types of validations) but that’s the game of evolution.

My friend Cem has a saying, security is often an exercise of re-arranging deck chairs on a sinking ship.

As we move closer to an encrypted web sometimes I am reminded of this, no matter what I am sure we will find more of these secondary effects which will give us an opportunity to focus on shoring up these other systems, just like we have with TLS.

Ryan

P.S. Thanks to Josh at ISRG and Andrew Whalley in the Chrome team at Google for some related conversations that helped me solidify my thoughts on this topic. And also thanks to Vincent Lynch for his review of the post.

XMLDSIG and XAdES in the browser and Node

It is great that we have a language like Javascript that we can use in both client and server applications. With that said one of the challenges both the browser and server environments have compared to say Java or .NET is a fairly weak set of class libraries to build upon.

This is especially true when it comes to security technologies, this is the foundation of most of our OSS work at Peculiar Ventures.

Our most recent project is a XMLDSIG library we call XAdESjs, it is based on WebCrypto and as a result with an appropriate polyfill it works on Node as well as it does in the browser.

With it and a few lines of code you can now sign and verify XMLDSIG and XAdES-BES signatures on these platforms, for example a verify on Node might look like this:

var xadesjs = require(“./xadesjs/built/xades.js”);
var DOMParser = require(“xmldom”).DOMParser;
var WebCrypto = require(“./node-webcrypto-ossl”).default;

xadesjs.Application.setEngine(“OpenSSL”, new WebCrypto());

var fs = require(“fs”);
var xmlString = fs.readFileSync(“./xadesjs/test/static/valid_signature.xml”,”utf8″);

var signedDocument = new DOMParser().parseFromString(xmlString, “application/xml”);
var xmlSignature = signedDocument.getElementsByTagNameNS(“http://www.w3.org/2000/09/xmldsig#”, “Signature”);

var signedXml = new xadesjs.SignedXml(signedDocument);
signedXml.LoadXml(xmlSignature[0]);
signedXml.CheckSignature()
.then(function (signedDocument) {
console.log(“Successfully Verified”);
})
.catch(function (e) {
console.error(e);
});

Though we only support the most basic forms of XAdES at this time it is enough to verify the EU Trust Service Provider List (EUTSL).

We intend to add more of XAdES to the library in the future, though we have no schedule for that at this time.

There is still lots to do so please consider contributing.

Ryan

Escaping the Same-origin Policy for PKIjs

PKIjs enables you to build rich PKI-aware applications inside of the browser, that said the browser implements a security policy called the Same-origin Policy that restricts the code running on the page from accessing resources served from other locations.

There is also a related capability that allows a remote server to state what origins can interact with it, this capability is called Cross-Origin Resource Sharing (CORS).

This background is important since the associated standards for PKI presume the client will be able to reach the Certificate Authority that issued the certificate to check revocation status (OCSP and CRL) as well as potentially fetch issuer certificates.

Unfortunately, the WebPKI CRL and OCSP responders do not set these headers, as such for a web page to fetch these resources an intermediate proxy is needed to enable your web application to access these servers.

There are lots of great resources on how to configure Nginx as forward-proxy. The problem is you do not want to be used as an open forward proxy. In this case, what we want to do is have a virtual host that will proxy request on behalf of the client to the appropriate origin server. For example sake, let’s say we have a host proxy.example.com. It is straightforward to configure Nginx as an open forward proxy and there are a lot of examples on the internet showing how to do this. That said we do not want to create an open proxy to be abused so we want some constraints:

  1. Only forward proxy to a whitelisted set of hosts,
  2. Only proxy specific methods (POST and GET),
  3. Rate limited the client to make it more difficult to abuse.

To enable this we want to be able to pass a query string to Nginx that contains the URL we want the request forwarded to, for example, https://proxy.example.com?url={urlencoded url}

A configuration that does this might look something like the following:

map "$request_method:$uri" $whitelist {
default "deny";
~^POST:/&url=http:/timestamp.globalsign.com "allow";
~^GET:/&url=http:/ocsp2.globalsign.com "allow";
}

limit_req_zone $binary_remote_addr zone=proxy:10m rate=5r/m;

server {
 resolver 8.8.8.8;
 listen 80 default_server;
 location / {
 limit_req zone=proxy burst=5;
 if ($whitelist = deny) { return 403; break; }
 if ($uri ~ \&url\=(https?):/([^\/]*)(.+)) { set $myproto $1; set $myhost $2; set $myuri $3; }
 if ($myproto = http) { proxy_pass http://$myhost$myuri; break; }
 if ($myproto = https) { proxy_pass https://$myhost$myuri; break; }
 }
}

NOTE: It seems that Nginx has a bug where when tokenizing it messes with the URL-encoded value stripping out some characters (including the /). To work around this in the above configuration we match on a single slash, this still works because this stripping appears consistent but does not effect the $uri value which is passed to the origin server.

NOTE: Unfortunately to accomplish the above we needed to use the if statement which has some downsides. If you know of how to accomplish the above without the use of them, or how to use less of them please let me know.

With this, the browser is now able to make requests to a limited set of hosts once every 12 seconds.

But what if you want this forward proxy(proxy.example.com) to exist in a different domain  from the application (pkijsapp.example.com)?  By default, the browser will not allow this but thankfully we can use  Cross-Origin Resource Sharing (CORS) to tell the clients they can send requests to our proxy, you do this by returning two additional headers to the client:

Access-Control-Allow-Origin: http://pkijsapp.example.com
Access-Control-Allow-Methods: POST, GET

With these two headers set, the browser will allow the pkijsapp.example.com application to send both POST and GETs to our proxy.

But what if we want to communicate with multiple servers? Unfortunately, the CORS specification only allows the server to set a single origin in this header. It recommends that cases that require access to multiple origins set the header dynamically. This, of course, requires the server to have knowledge of what the client needs and if you are building a Single Page Application it’s quite likely the server doesn’t have that context.

Thankfully it does support a wildcard so if you have multiple application domains you want your proxy to be accessible from you can specify *:

Access-Control-Allow-Origin: *

This approach works around the multiple origin limitations of CORS but has its own issues, for example:

  1. Your server is now an unauthenticated network proxy that can be abused,
  2. If the servers you include in the whitelist can also serve active content they become useful to an attacker,
  3. Your server now has knowledge of which certificates are being validated by the client,

Neither of these approaches is perfect but they both allow you to get the information necessary to validate certificates using PKIjs within the browser.

Ryan

Understanding risks and avoiding FUD

Disclaimer: This post represents personal opinions and thoughts, and does not represent the views or positions of my employer Google, or Let’s Encrypt where I am a member of their advisory board.

The first step in building a complex system or protocol that has any security needs at all is to model the threats that the system is exposed to. Without a deep understanding of the system and the threats it is exposed to it is not possible to effectively secure it from a motivated attacker.

A key part of this process is understanding the abilities, motivations and the perspective of the attacker. This not only helps you understand what it is they are looking for, but what they will do with the surface area they have access to.

I bring this up because today TrendMicro published a blog post titled “Let’s Encrypt Now Being Abused By Malvertisers” and after reading it, I am convinced the authors are not looking at this topic with that frame of mind. Additionally, it seems they either intentionally or unintentionally omit and/or misrepresent details that are imperative to understand the incident they discuss.

In this post, I try to look more critically at what happened and identify what the core issues at play actually were.

Types of certificates

Before I get to the details I want to provide some background. First it is important to understand that there are, broadly speaking, three types of SSL certificates that Certificate Authorities issue, each with increasing levels of “identity assurance”.

The first is what is referred to as a “Domain Validated” or DV certificates. To obtain a DV certificate, one must only prove that they control the host or domain to be certified.

The next is referred to as an “Organization Validated” or OV certificates. To obtain an OV certificate, one must prove control of the domain using the same mechanisms allowed for DV but must also prove two additional things. First is who the legal entity that controls the domain is. Second is that the requester is acting on behalf of that entity. Browsers do not treat these certificates any different than a DV certificate as such they offer the relying party no additional value.

Finally, there is “Extended Validation” or EV certificates. These are logically the same as OV except the requirements that must be met when verifying the legal entity and requestor affiliation are higher. Since knowing the entity that controls a given host or domain can provide useful information to a relying party browsers display a “Green Bar” with the legal entity name visible within it for these certificates.

Let’s Encrypt issues only Domain Validated certificates. To put this in context today around 5% of certificates on the Internet are EV. This is important to understand in that the certificates issued by Let’s Encrypt are effectively no less “secure” or “validated” than the DV certificates issued by other Certificate Authorities. This is because all CAs are held to the same standards for each of the certificate types they issue.

Request validation

So what exactly are the processes a Certificate Authority follows when validating a request for a Domain Validated certificate? The associated requirements document is nearly fifty pages long so to save you muddling through that I will summarize the requirement:

  • the requestor controls the key being bound to the account or key being certified,
  • the requestor controls the host or domain being certified,
  • that issuing the certificate would not give the key holder ability to assert an identity other than what has been verified,
  • the hosts or domains being certified are not currently suspected of phishing or other fraudulent usages.

It also suggests (but does not require) that CAs implement something called CA Authorization (CAA) Resource Records. These are special DNS records that let a domain owner state which Certificate Authority it legitimately uses for certificates.

Let’s Encrypt

If you want to see for yourself what Let’s Encrypt does for each of these requirements you can review their code, that said it can be summarized as:

Proof of possession: Ensure the requestor can sign a message with the key that will be associated with their account and another for the key associated with their certificate.

Domain control: They support several mechanisms but they all require someone in control of the domain or host to perform an action only a privileged user could.

They also check the Public Suffix List (PSL) on each request. They use this to rate limiting certificate issuance of subdomains not on the PSL.

They also do not issue wildcard certificates.

Domain intent: They implement strict support for CAA records, if such a record is found and Let’s Encrypt is not listed the request will be denied.

Fraudulent usage: Every host or domain requested is checked against the Google Safe Browsing service.

This is, at a high level, the same thing every CA is supposed to do for every DV, OV or EV SSL certificate they issue. If they do not, they would not pass their WebTrust audit. The only place there is any room for interpretation is:

  1. Which domain control approaches they support,
  2. How broadly in their orders they use the PSL,
  3. If they support CAA,
  4. Which data source they use for fraudulent use detection.

On fraudulent use detection I know of CAs that utilize various pre-issuance approaches. Some use private databases; others may use Google Safe Browsing, APWG, PhishTank or some combination of all of these. I should add that the Google Safe Browsing API that Let’s Encrypt uses has a reputation of being one of the best available sources for doing these kinds of checks. I know of only a few who do any post-issuance checking of these data sources.

But what about the infamous Let’s Encrypt certificate issuance automation? Contrary to popular belief Let’s Encrypt is not the first, or even the only CA that automates 100% of the issuance process. They are also not the only ones who offer client automation to request the certificate and configure SSL.

Just ask yourself how to providers like CloudFlare or Hosting Providers get and configure SSL certificates in seconds if it is done manually?

If that is the case how is Let’s Encrypt different? I would say there are two very visible differences:

  1. They are 100% free with no limitations on who can get certificates,
  2. Their practices are the most transparent of the publicly trusted CAs.

The FUD

There is a lot of FUD in the TrendMicro post so please bear with me.

The first that jumps out is that the authors essentially say they saw this coming. It’s framed this way in an attempt to convince the reader this was only possible because of Let’s Encrypt.

Unfortunately, the potential for Let’s Encrypt being abused has always been present. Because of this, we have kept an eye out for malicious sites that would use a Let’s Encrypt certificate.

The problem with this argument is that there really is nothing special about what Let’s Encrypt is doing. In fact, Netcraft recently did a post titled Certificate authorities issue SSL certificates to fraudsters where they find numerous other well-respected CAs have issued certificates to people who later used them for bad deeds.

The issue here is that fraudsters understand CAs check orders for fraud pre-issuance to avoid posts just like the one from TrendMicro we are discussing, as a result attackers wait until after a certificate is issued to perpetrate fraud with the associated hosts and domains.

Any technology that is meant for good can be abused by cybercriminals, and Let’s Encrypt is no exception. As a certificate authority ourselves we are aware of how the SSL system of trust can be abused.

This statement is supposed to suggest that if Let’s Encrypt did not issue the associated certificate the attack in question would not be possible. It again goes on to suggest that TrendMicro is somehow different. Recall however that all CAs are subject to the same requirements for verifying domain control, the core difference between Let’s Encrypt and TrendMicro as CAs is that TrendMicro only issues Organization Validation and Extended Validation certificates.

Maybe that is what they are driving at? There is a valid argument to be made the increased cost and complexity getting an OV certificate makes it harder for an attacker to get an SSL certificate because they must also prove organization details. With that said, as long as DV certificates are allowed the user’s risk is the same.

It is worth noting though that it is quite possible to spoof the material necessary to get a OV certificate. In fact, there are numerous ways one can (very inexpensively) produce “false” but “verifiable” documentation that would meet the OV verification bar. But the argument they are making here is a red herring, I will explain why in a bit

Maybe then the issue is that Let’s Encrypt is somehow at fault because they issue certificates via a fully automated mechanism?

A certificate authority that automatically issues certificates specific to these subdomains may inadvertently help cybercriminals, all with the domain owner being unaware of the problem and unable to prevent it.

If so, the core issue is one that touches TrendMicro also. This is because they also issue certificates “in minutes”, something only possible with automation. This too is a red herring though.

Maybe the issue is a result of Let’s Encrypt not meeting the same requirements of other CAs?

Let’s Encrypt only checks domains that it issues against the Google safe browsing API;

As I have called out above, that is simply not true and all you need to do is check their public source repository to confirm yourself.

So maybe the problem is Let’s Encrypt just is not playing an active role in keeping you safe on the internet.

Security on the infrastructure is only possible when all critical players – browsers, CAs, and anti-virus companies – play an active role in weeding out bad actors.

There is a word for this sort of argument it is ‘specious’. The reality is when you look at the backers of Let’s Encrypt (which in full disclosure includes my employer) you see the who’s who of privacy and security.

Well then if the issue is not Let’s Encrypt, maybe it is Domain Validated certificates? Their post does not directly make this claim but by suggesting TrendMicro would not have issued the attacker a certificate they may be trying to subtly suggest as much since they don’t issue DV certificates.

The problem is even if DV did not exist I am confident a motivated attacker could easily produce the necessary documentation to get an OV certificate. It is also worth noting that today that 70% of all certificates in use only offer the user the assurance of a Domain Validated certificate.

OK so maybe the core issue is that SSL was available to the attacker at all? The rationale being if the site hosting the ad was served over SSL and the attacker did not serve their content over SSL the users would have seen the mixed content indicator which might have clued the user into the fact something afoot. The problem with this argument is that study after study has shown that the subtle changes in the lock icon are simply not noticeable by users, even to those who have been taught to look for them.

So if the the above points were not the issue what was?

How was this attack carried out? The malvertisers used a technique called “domain shadowing”. Attackers who have gained the ability to create subdomains under a legitimate domain do so, but the created subdomain leads to a server under the control of the attackers. In this particular case, the attackers created ad.{legitimate domain}.com under the legitimate site. Note that we are disguising the name of this site until its webmasters are able to fix this problem appropriately.

There you go. The attacker was able to register a subdomain under a parent domain and as such was able to prove control of any hosts associated with it. It had nothing to do with SSL, the attacker had full control of a subdomain and the attack would have still worked without SSL.

Motivations

With this post TrendMicro is obviously trying to answer a questions their customers must be asking: Why should I buy your product when I can get theirs for free?

DigiCert, GoDaddy, Namecheap as well as others have done their own variation of FUD pieces like this trying to discourage the use of “Free Certificates” and discredit their issuers. They do this, I assume, in response to the fear that the availability of free certificates will somehow hurt their business. The reality is there are a lot of things Let’s Encrypt is not, and will probably never be.

Most of these things are the things commercial Certificate Authorities already do and do well. I could also go on for hours on different ways they could further improve their offerings and better differentiate their products to grow their businesses.

They should, instead of trying to sell fear and uncertainty, focus on how they can make their products better, stickier, and more valuable to their customers.

That said, so far it looks like they do not have much to worry about. Even though Let’s Encrypt has issued over 250,000 certificates in just a few months almost 75% of the hosts the associated with them did not have certificates before. The 25% who may have moved to Let’s Encrypt from another CA were very likely customers of the other free certificates providers and resellers, where certificates are commonly sold for only a few dollars.

In short, it looks like Let’s Encrypt’s is principally serving the long tail of users that existing CAs have historically failed to engage.

Threat Model

When we look critically at what happened in the incident TrendMicro discusses can clearly identify two failures:

  1. The attacker was able to register a legitimate subdomain due to a misconfiguration or vulnerability,
  2. A certificate was issued for a domain and the domain owner was not aware of it.

The first problem would have potentially been prevented if a formal security program was in place and the system managing the domain registration process had been threat modeled and reviewed for vulnerabilities.

The second issue could have also been caught through the same process. I say “could”, because  not everyone is aware of Certificate Transparency (CT) and CAA which are the tools one would use to mitigate this risk.

At this time CT is is not mandated by WebTrust but Chrome does require it for EV certificates as a condition of showing the “Green Bar”. That said even though it is not a requirement Let’s Encrypt chooses to publish all of the certificates they issue into the logs. In fact, they are the only Certificate Authority I am aware of who does this for DV certificates.

This enables site owners, like the one in question to register with log monitoring services, like the free and professional one offered by DigiCert, and get notified when such a certificate is issued.

As mentioned earlier CAA is a pre-issuance check designed for this specific case, namely how to I tell a CA I do not want them issuing certificates for my domain.

Until all CAs are required to log all of the SSL certificates they issue into CT Logs and are required to use CAA these are not reliable tools to catch mississuances. That said since Let’s Encrypt does both they would have caught this particular case and that is a step in the right direction.

 

[Edited January 9th 2016 to fix typos and make link to trend article point to the Internet Archive Wayback Machine]

The PKCS#12 standard needs another update

PKCS#12 is the defacto file format for moving private keys and certificates around. It was defined by RSA and Microsoft in the late 90s and is used by Windows extensively. It was also recently added to KIMP as a means to export key material.

As an older format, it was designed with support for algorithms like MD2, MD5, SHA1, RC2, RC4, DES and 3DES. It was recently standardized by IETF RFC 7292 and the IETF took this opportunity to add support for SHA2 but have not made an accommodation for any mode of AES.

Thankfully PKCS #12 is based on CMS which does support AES (see RFC 3565 and RFC 5959). In theory, even though RFC 7292 doesn’t specify a need to support AES,  there is enough information to use it in an interoperable way.

Another standard used by PKCS#12 is PKCS #5 (RFC 2898), this specifies the mechanics of password-based encryption. It provides two ways to do this PBES1 and PBES2, more on this later.

Despite these complexities and constraints, we wanted to see if we could provide a secure and interoperable implementation of PKCS#12 in PKIjs since it is one of the most requested features. This post documents our findings.

Observations

Lots of unused options

PKCS#12 is the swiss army knife of certificate and key transport. It can carry keys, certificates, CRLs and other metadata. The specification offers both password and certificate-based schemes for privacy and integrity protection.

This is accomplished by having an outer “integrity envelope” that may contain many “privacy envelopes”.

When using certificates to protect the integrity of its contents, the specification uses the CMS SignedData message to represent this envelope.

When using passwords it uses an HMAC placed into its own data structure.

The use of an outer envelope containing many different inner envelopes enables the implementor to mix and match various types of protection approaches into a single file. It also enables implementers to use different secrets for integrity and privacy protection.

Despite this flexibility, most implementations only support the following combination:

  1. Optionally using the HMAC mechanism for integrity protection of certificates
  2. Using password-based privacy protection for keys
  3. Using the same password for privacy protection of keys

NOTE: OpenSSL was the only implementation we found that supports the ability to use a different password for the “integrity envelope” and  “privacy envelope”. This is done using the “twopass” option of the pkcs12 command.

The formats flexibility is great. We can envision a few different types of scenarios one might be able to create with it, but there appears to be no documented profile making it clear what is necessary to interoperate with other implementations.

It would be ideal if a future incarnation of the specification provided this information for implementers.

Consequences of legacy

As mentioned earlier there are two approaches for password based encryption defined in PKCS#5 (RFC 2989).

The first is called PBES1, according to the RFC :

PBES1 is recommended only for compatibility with existing
applications, since it supports only two underlying encryption
schemes, each of which has a key size (56 or 64 bits) that may not be
large enough for some applications.

The PKCS#12 RFC reinforces this by saying:

The procedures and algorithms
defined in PKCS #5 v2.1 should be used instead.
Specifically, PBES2 should be used as encryption scheme, with PBKDF2
as the key derivation function.

With that said it seems, there is no indication in the format on which scheme is used which leaves an implementor forced with trying both options to “just see which one works”.

Additionally it seems none of the implementations we have encountered followed this advice and only support the PBES1 approach.

Cryptographic strength

When choosing cryptographic algorithm one of the things you need to be mindful of is the minimum effective strength. There are differing opinions on what each algorithm’s minimum effective strength is at different key lengths, but normally the difference not significant. These opinions also change as computing power increases along with our ability to break different algorithms.

When choosing which algorithms to use together you want to make sure all algorithms you use in the construction offer similar security properties If you do not do this the weakest algorithm is the weakest link in the construction. It seems there is no guidance in the standard for topic, as a result we have found:

  1. Files that use weak algorithms protection of strong  keys,
  2. Files that use a weaker algorithm for integrity than they do for privacy.

This first point is particularly important. The most recently available guidance for minimum effective key length comes from the German Federal Office for Information Security, BSI. These guidelines, when interpreted in the context of PKCS #12, recommend that a 2048-bit RSA key protection happens using SHA2-256 and a 128-bit symmetric key.

The strongest symmetric algorithm specified in the PKCS #12 standard is 3DES which only offers an effective strength of 112-bits.  This means, if you believe the BSI, it is not possible to create a standards compliant PKCS#12 that offer the effective security necessary to protect a 2048-bit RSA key.

ANSI on the other hand, currently recommends that 100-bit symmetric key is an acceptable minimum strength to protect a 2048-bit RSA key (though this recommendation was made a year earlier than the BSI recommendation).

So if you believe ANSI, the strongest suite offered by RFC 7292 is strong enough to “adequately” protect such a key, just not a larger one.

The unfortunate situation we are left with in is that it is not possible to create a “standards compliant” PKCS12 that support modern cryptographic recommendations.

Implementations

OpenSSL

A while ago OpenSSL was updated to support AES-CBC in PKCS#8 which is the format that PKCS#12 uses to represent keys.  In an ideal world, we would be using AES-GCM for our interoperability target but we will take what we can get.

To create such a file you would use a command similar to this:

rmh$ openssl genrsa 2048|openssl pkcs8 -topk8 -v2 aes-256-cbc -out key.pem

Generating RSA private key, 2048 bit long modulus

……………+++

……………….+++

e is 65537 (0x10001)

Enter Encryption Password:

Verifying – Enter Encryption Password:
rmh$ cat key.pem

—–BEGIN ENCRYPTED PRIVATE KEY—–

—–END ENCRYPTED PRIVATE KEY—–

If you look at the resulting file with an ASN.1 parser you will see the file says the Key Encryption Key (KEK) is aes-256-cbc.

It seems the latest OpenSSL (1.0.2d) will even let us do this with a PKCS#12, those commands would look something like this:

openssl genrsa 2048|openssl pkcs8 -topk8 -v2 aes-256-cbc -out key.pem

openssl req -new -key key.pem -out test.csr

openssl x509 -req -days 365 -in test.csr -signkey key.pem -out test.cer

openssl pkcs12 -export -inkey key.pem -in test.cer -out test.p12 -certpbe AES-256-CBC -keypbe AES-256-CBC

NOTE: If you do not specify explicitly specify the certpbe and keypbe algorithm this version defaults to using pbewithSHAAnd40BitRC2-CBC to protect the certificate and pbeWithSHAAnd3-KeyTripleDES-CBC to protect the key.

RC2 was designed in 1987 and has been considered weak for a very long time. 3DES is still considered by many to offer 112-bits of security though in 2015 it is clearly not an algorithm that should still be in use.

Since it supports it OpenSSL should really be updated to use aes-cbc-256 by default and it would be nice if  support for AES-GCM was also added.

NOTE: We also noticed if you specify “-certpbe NONE and -keypbe NONE” (which we would not recommend) that OpenSSL will create a PKCS#12 that uses password-based integrity protection and no privacy protection.

Another unfortunate realization is OpenSSL uses an iteration count of 2048 when deriving a key from a password, by today’s standards is far too small.

We also noticed the OpenSSL output of the pkcs12 command does not indicate what algorithms were used to protect the key or the certificate, this may be one reason why the defaults were never changed — users simply did not notice:

rmh$ openssl pkcs12 -in windows10_test.pfx

Enter Import Password:

MAC verified OK

Bag Attributes

   localKeyID: 01 00 00 00

   friendlyName: {4BC68C1A-28E3-41DA-BFDF-07EB52C5D72E}

   Microsoft CSP Name: Microsoft Base Cryptographic Provider v1.0

Key Attributes

   X509v3 Key Usage: 10

Enter PEM pass phrase:

Bag Attributes

   localKeyID: 01 00 00 00

subject=/CN=Test/O=2/OU=1/[email protected]/C=<\xD0\xBE

issuer=/CN=Test/O=2/OU=1/[email protected]/C=<\xD0\xBE

—–BEGIN CERTIFICATE—–

—–END CERTIFICATE—–

Windows

Unfortunately, it seems that all versions of Windows (even Windows 10) still produces PKCS #12’s using pbeWithSHAAnd3-KeyTripleDES-CBC for “privacy” of keys and privacy of certificates it uses pbeWithSHAAnd40BitRC2-CBC. It then relies on the HMAC scheme for integrity.

Additionally it seems it only supports PBES1 and not PBES2.

Windows also uses an iteration count of 2048 when deriving keys from passwords which is far too small.

It also seems unlike OpenSSL, Windows is not able to work with files produced with more secure encryption schemes and ciphers.

PKIjs

PKIjs has two, arguably conflicting goals, the first of which is to enable modern web applications to interoperate with traditional X.509 based applications. The second of which is to use modern and secure options when doing this.

WebCrypto has a similar set of guiding principles, this is why it does not support weaker algorithms like RC2, RC4 and 3DES.

Instead of bringing in javascript based implementations of these weak algorithms into PKIjs we have decided to only support the algorithms supported by webCrypto (aes-256-cbc, aes-256-gcm with SHA1 or SHA2 using PBES2.

This represents a tradeoff. The keys and certificates and exported by PKIjs will be protected with the most interoperable and secure pairing of algorithms available but the resulting files will still not work in any version of Windows (even the latest Windows 10 1511 build).

The profile of PKCS#12 PKIjs creates that will work with OpenSSL will only do so if you the -nomacver option:

openssl pkcs12 -in pkijs_pkcs12.pfx -nomacver


This is because OpenSSL uses the older PBKDF1 for integrity protection and PKIjs is using the newer PBKDF2, as a result of this command integrity will not be checked on the PKCS#12.

With that caveat, here is an example of how one would generate a PKCS#12 with PKIjs.

Summary

Despite its rocky start, PKCS#12 is still arguably one of the most important cryptographic message formats. An attempt has been made to modernize it somewhat, but they did not go far enough.

It also seems OpenSSL has made an attempt to work around this gap by adding support for AES-CBC to their implementation.

Windows on the other hand still only appear to support only the older encryption construct with the weaker ciphers.

That said even when strong, modern cryptography are in use we must remember any password-based encryption scheme will only be as secure as the password that is used with it. As a proof point, consider these tools for PKCS#12 and PKCS#8 that make password cracking trivial for these formats.

We believe the storage and transport of encrypted private keys is an important enough topic that it deserves a modern and secure standard. With that in mind recommend the following changes to RFC 7292 be made:

  • Deprecate the use of all weaker algorithms,
  • Make it clear both AES-CBC and AES-GCM should be supported,
  • Make it clear what the minimal profile of this fairly complex standard is,
  • Require the support of PBES2,
  • Be explicit and provide modern key stretching guidance for use with PBKDF2,
  • Clarify how one uses PBMAC1 for integrity protection,
  • Require that the certificates and the keys are both protected with the same or equally secure mechanisms.

As for users, there are a few things you can do to protect yourself from the associated issues discussed here, some of which include:

  • Do not use passwords to protect your private keys. Instead generated symmetric keys or generated passwords of an appropriate lengths (e.g. “openssl rand -base64 32”),
  • When using OpenSSL always specify which algorithms are being used when creating your PKCS#12 files and double check those are actually the algorithms being used,
  • Ensure that the algorithms you are choosing to protect your keys offer a minimum effective key length equal to or greater than the keys you will protect,
  • Securely delete any intermediate copies of keys or inputs to the key generation or export process.

Ryan & Yury