00:00:16.560
Hello, my name is Martin. I'm a member of the Ruby core team, and I am one of the maintainers of the Ruby OpenSSL extension. As of last year, I have also been a freelancer. I'm from Germany, and today I want to talk about cryptography in general, but specifically about Krypt.
00:00:33.719
What I want to tell you is that cryptography is hard, and it's actually very difficult to do it correctly. You might even think that you should never attempt it, but at times, it becomes necessary. The result can be frustrating because it's just so complex, and it seems that only a select few people really understand it. For example, Snoop Dogg apparently knows a thing or two about it, but there aren't many others like him.
00:00:57.399
So, the real question is: if cryptography is hard, do crypto APIs have to be difficult as well? There are two opposing forces at work here. On one hand, there are programmers who only care about the end result being secure, and they don't bother with the complexities of cryptography. On the other hand, there are experts who write crypto code daily and want full control over all the parameters.
00:01:18.960
However, let’s face it—security in everyday development is a pain. Most people avoid it because if done correctly, no one notices; but if it’s done wrong, that’s the only time anyone pays attention. You will likely never come home and tell your spouse, 'I wrote some crypto code.' Consequently, I argue that cryptography and security are the scourge of software development—they're a huge annoyance. Yet, we cannot overlook them; they can lead to serious issues.
00:02:01.280
I also claim that this makes cryptography the joy of software development; good design should make complex tasks easier. We have many examples of this happening outside cryptography. For instance, managing databases is hard; that's why we have ActiveRecord for that. Threads are difficult to handle, but we have STM and actors. As Ruby developers, we know memory management can be tricky, yet we have garbage collectors to help.
00:02:20.560
So, if we have solutions for these other complexities, why hasn't the same approach been applied to cryptography? One reason is that the experts require full control over all parameters and details, which creates a conflict with everyday developers who wish to avoid dealing with the grunt work.
00:02:52.000
We face two opposing forces: on one side, we have abstraction, which makes things easier, while on the other side, there's the risk of oversimplifying matters to the point where essential functionalities can no longer be achieved. In cryptography, there's no golden middle; there isn't one solution that fits all.
00:03:29.600
Consequently, in the past, we've seen libraries targeted at specific camps. If you belong to the full-control camp, you might use something like OpenSSL or the Java security libraries, both of which provide granular control. For users who prioritize security without needing to delve deep into the details, options have been far fewer. Examples of simpler libraries that aim to provide user-friendly interfaces include Kissa, Salted Passwords, and libsodium.
00:03:53.360
So, if we already have some tools that make life easier, why not just use them and put an end to the problem? First of all, some people need the specifics. Additionally, we must consider legacy applications that may rely on algorithms and protocols no longer deemed secure by today's standards. I believe we need both: full control when necessary and user-friendly tools when they suffice.
00:04:32.360
Now, why can’t we have a combined approach that brings together full control and simplicity? The not-so-revolutionary idea is to merge these concepts into one library. This is where Krypt comes into the picture.
00:04:59.680
You might be asking yourselves right now, 'What is Krypt and what does it do?' Let’s start from the beginning: who is working on Krypt? Currently, there are five people involved—myself, Nahi, Vpol, Bruno, and Douglas. My colleague Nahi worked on Krypt through last year’s Google Summer of Code for JRuby.
00:05:10.480
A common question we face is whether Krypt will eventually replace OpenSSL or any other crypto library you currently use. The answer is no. Krypt sees itself more as a framework; it utilizes existing libraries to implement the core primitives of cryptography. We can exist alongside these libraries, wrapping them in a common Krypt interface. This provides a low-level API that makes it easy to use if you require details.
00:06:05.000
For example, Krypt supports digest algorithms, as well as symmetric and asymmetric encryption in the form of ciphers and signatures. Additionally, a significant part of Krypt's role is the integration of ASN.1, which serves to define data structures and is the de-facto standard in cryptography. Though everyone seems to dislike it, it’s what we have to work with.
00:06:28.960
Now, if you belong to the camp that just wants to write secure code and doesn't care too much about cryptographic details, how can Krypt assist you? Krypt uses this low-level API that already exists to create a higher-level API that is easy to use and secure by default. You might wonder about the significance of a higher-level API—after all, few libraries offer one. To understand its importance, let’s explore some practical examples of what can go wrong today.
00:07:12.320
In the first example, I'll illustrate data encryption as described in the OpenSSL documentation. This demonstrates a secure encryption process. Key generation is performed using a cryptographically secure random generator, along with the initialization vector (IV). In practice, however, I've often witnessed people using textual passwords instead of randomly generated keys, which is dangerous because this significantly restricts entropy. A weak password can be easily brute-forced.
00:08:45.760
Furthermore, many developers choose the wrong encryption mode, often opting for ECB, which is incorrect in about 95% of cases. Generally, using CBC or authenticated encryption modes like GCM is recommended; if people do select other modes, they may forget to use the initialization vector, which is essential for modes other than ECB.
00:10:02.320
OpenSSL allows the omission of IV, defaulting to a deterministic value that can lead to severe vulnerabilities, so IV should always be generated manually using a secure random generator. Even the API design can lead to confusion—developers often misunderstand that they need to explicitly call methods for encryption/decryption and finalize the cipher. This should ideally be regarded as implicit.
00:10:49.440
In another scenario regarding secure password storage, it's important to use bcrypt due to its sensible API. However, some projects may specifically require using PBKDF2, which is an established standard, especially in the banking or government sectors.
00:11:14.240
This hashing algorithm has four parameters, including the password, salt, iteration count, and output length. Common mistakes include using the password itself as the salt, forcing a situation where two users with identical passwords yield the same hash, which is counterproductive to the purpose of salting.
00:12:00.160
Others choose iteration counts that are far too low, thinking conservative values will avoid denial of service. However, a count of just 10 isn't enough; thousands and tens of thousands should be the target range. Even when it comes to defining the output length, users often select an insecure figure, compromising their hashing integrity.
00:12:43.959
The API itself can present challenges, as developers frequently need to refer to documentation to determine the correct order of parameters—confusion abound. Misunderstanding API functions for password hashing and employing older methods like MD5 can expose them to threats. We cannot afford to rely on insecure practices from the past.
00:13:16.640
Next, let’s discuss certificate validation, which can also be cumbersome to implement. To do it correctly, developers must complete online revocation checks, such as checking Certificate Revocation Lists (CRLs) or using OCSP, which requires HTTP access.
00:13:51.600
The challenge is that OpenSSL doesn’t accommodate external dependencies, making it extremely challenging for developers. Adhering to a policy against external resources no longer works well in today’s development climate.
00:14:26.960
Having seen many bad examples, let’s now explore how Krypt aims to improve these situations with its API. It is designed to allow developers to express their intentions without excessive parameters or boilerplate. When it comes to encryption, there should be a straightforward method that establishes a key between all parties.
00:15:12.320
When it's time to encrypt or decrypt data, it should be as simple as writing it. For password hashing, simply instruct Krypt to hash a password, and if you need to verify an incoming password against an existing hash, call it to verify the hash.
00:15:29.200
In previous libraries, validation often returned a Boolean indicating success or failure. This approach can be dangerous since developers might forget to check the return value. Instead, Krypt will raise an error if validation fails, ensuring developers address it.
00:15:49.960
For certificate validation, you would simply take your certificate and check if it’s valid, eliminating the need for multiple parameters. This allows for fundamental customization while ensuring a user-friendly experience, facilitating security by default. It's crucial that security be easy and just work.
00:16:51.680
So, can we genuinely replace OpenSSL with something like Krypt? I believe we can. The solution lies in using protocols that enable us to create an interface based on existing libraries for cryptographic needs.
00:17:40.560
Krypt has numerous advantages, including a distinction between high-level and low-level APIs. For instance, it is designed to include a wealth of tests. While C is notorious for being difficult to test, Ruby fosters a more robust testing culture.
00:18:06.760
By utilizing RSpec tests and our tool called FuzzBird, we automatically test Krypt by bombarding it with random data. This approach ensures early detection of vulnerabilities, ultimately promoting robust security practices.
00:18:46.760
Documentation is critical, particularly for security libraries, as they are complex and potentially dangerous. A strong documentation effort can vastly improve user outcomes, and many existing security libraries fall short in this area. Krypt aims to use as much Ruby code as possible, allowing us to avoid introducing buffer overflows or similar problems associated with languages that require native code.
00:19:29.440
While it’s unlikely we can completely eliminate native code, our intent is to wrap existing libraries with a common Krypt interface, maintaining native code largely in the background, hidden from users. This approach provides us with the flexibility to choose which libraries we use behind the scenes.
00:20:01.440
Why go to all this effort? It enables true platform interoperability. We envision the ability to write code that operates consistently across all Ruby platforms. Even if you think you’ll never write cryptographic code, rest assured your applications will likely employ HTTPS.
00:20:36.440
If HTTPS fails, then Ruby fails as an ecosystem. Without proper HTTPS implementations, projects like Bundler and RubyGems are jeopardized. Currently, OpenSSL is the go-to for achieving HTTPS, but it’s not universally available across all platforms.
00:21:05.880
For example, Java lacks OpenSSL by default, and Windows also doesn’t come bundled with OpenSSL by default. Apple has recently deprecated OpenSSL as well, which could lead to future unavailability. Exclusively relying on native libraries leads us down a precarious path of recurring mistakes.
00:21:31.960
Our ultimate goal aligns with what the Java ecosystem has achieved. Writing libraries in Java lends itself to cross-platform compatibility, ensuring they work wherever Java runs. Krypt aims to do the same for Ruby, concentrating heavily on writing in Ruby, and employing native parts only when strictly necessary.
00:22:20.760
Utilizing Foreign Function Interface (FFI) allows us to interface seamlessly with native code and select modules that function across JRuby, thereby enhancing the runtime of cryptographic operations.
00:23:09.240
I have a demonstration to illustrate our design. Suppose you instantiate a SHA256 digest and employ it to examine a test value. The important takeaway here is that when utilized in MRI, the operation will use OpenSSL beneath—the C library. In contrast, using JRuby will implement it with Java's security library. The code remains unchanged across both implementations.
00:23:51.600
Whichever Ruby you choose, the same code will consistently yield the same output, allowing true platform interoperability. Should there arise a need to implement custom Ruby providers, the interface remains exposed at the Ruby level, allowing for potentially new and innovative cryptographic solutions.
00:24:20.640
We have plans to use a default, straightforward Ruby-based provider, ensuring Krypt remains accessible and functional for all uses, even when requiring heavier processing, users can easily install library upgrades that integrate more complex native solutions.
00:25:09.720
Looking to other programming languages, we see them facing similar issues with cryptography—especially C-based languages, which primarily couple their implementations with OpenSSL, leading to ongoing challenges. In contrast, Java libraries can leverage their security libraries, giving a bit more flexibility, although they lack access to the C libraries.
00:26:03.760
What if we could expand cryptographic access by making Krypt serve both as a Ruby library and additional language libraries like C or Java? With the foundations already built in these languages, Krypt’s practices could pioneer simplified accessibility across multiple ecosystems, providing high-level access to both Ruby and other programming languages.
00:26:57.920
This approach makes Krypt progressive. If we accomplish our goal of expanding access to cryptography, it can benefit not only Ruby developers but others in their respective languages too.
00:28:09.680
As we shift towards making these collaborations a reality, I anticipate that a thriving community will assist in our progress, helping us adjust Krypt to best suit user needs.
00:29:01.920
Thus far, their existing libraries serve well, offering usability and experimental capabilities for cryptographic solutions whereas Krypt can serve as a scalable foundation for Ruby applications.
00:29:56.080
So, we end our discussion with an open invitation. If you are interested in Krypt, please visit our GitHub page. Keep an eye on my blog for articles related to Krypt as they come up in the future.
00:30:18.240
Thank you all for listening. I look forward to any questions you may have.