Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions _blog-src/_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ url: "http://apiman.io" # the base hostname & protocol for your site
twitter_username: apiman_io
github_username: apiman
timezone: America/New_York
comments: true

# Build settings
markdown: kramdown
Expand Down
14 changes: 9 additions & 5 deletions _blog-src/_data/authors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@ eric_wittmann:
name: Eric Wittmann
email: eric.wittmann@redhat.com
github: https://www.github.com/ericwittmann
marc_savy:
name: Marc Savy
email: marc@rhymewithgravy.com
github: https://github.com/msavy
len_dimaggio:
name: Len DiMaggio
email: ldimaggi@redhat.com
github: https://github.com/ldimaggi
marc_savy:
name: Marc Savy
email: marc@rhymewithgravy.com
github: https://github.com/msavy
rachel_yordan:
name: Rachel Yordán
email: ryordan@redhat.com
github: https://github.com/kahboom
sbunciak:
name: Stefan Bunciak
email: sbunciak@redhat.com
github: https://github.com/sbunciak
github: https://github.com/sbunciak
18 changes: 18 additions & 0 deletions _blog-src/_includes/disqus.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<div id="disqus_thread"></div>
<script>
var disqus_config = function () {
this.page.url = '{{ post.url }}';
this.page.identifier = '{{ page.id || post.title }}';
};

(function() { // DON'T EDIT BELOW THIS LINE
var d = document, s = d.createElement('script');

s.src = '//apiman.disqus.com/embed.js';

s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript" rel="nofollow">comments powered by Disqus.</a></noscript>

1 change: 1 addition & 0 deletions _blog-src/_includes/head.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

<script src="http://www.apiman.io/latest/resources/jquery-1.11.1/js/jquery.min.js"></script>
<script src="http://www.apiman.io/latest/resources/bootstrap-3.3.0/js/bootstrap.min.js"></script>
<script id="dsq-count-scr" src="//apiman.disqus.com/count.js" async></script>

<!-- Canonical URL -->
{% if page.newUrl %}
Expand Down
1 change: 1 addition & 0 deletions _blog-src/_layouts/post.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,5 @@ <h1 style="color: #666; font-weight: bold" class="post-title section-header">{{
{{ content | modify_external_links: "^.*?[.]?(apiman[.]io|localhost).*?" }}
</article>

{% include disqus.html %}
</div>
140 changes: 140 additions & 0 deletions _blog-src/_posts/2016-04-08-data-encryption.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
---
layout: post
title: "Covering Your Assets: Data Encryption in API Management"
date: 2016-04-13 12:34:00 EST
author: rachel_yordan
categories: security gateway
---
:toc: macro
:toc-title:

In a world where APIs are quickly becoming the standard, most of us understand the importance of following best practices for API security. We authenticate, authorize and throttle requests. We encrypt the data that we share with other applications (hopefully!). But we often neglect one of the most essential components of the API layer: data storage.

////
Use this pattern to avoid asciidoctor rendering the HTML comment.
<!--more-->
////

toc::[]

== Encrypting Data as a Component of API Management Security

We often forget that APIs are not meant to protect data, rather, to share data across applications. While providers are certainly responsible for designing their APIs to be secure, we must be equally cautious about _each_ component of the API layer.

=== Data Storage in apiman

Designing, building, and maintaining an API can be a lot of work, often making security an afterthought. Using an API management platform can save you valuable time, allowing you to focus on other critical aspects of your business.

Apiman was designed with the goal of providing a secure, customizable platform for API providers that is easy to use. As an open source platform, it is highly extendable and maintained by a community of developers with the common goal of streamlining API management without compromising security.

*All sensitive data stored by apiman is fully encrypted* so that it is not stored in plain text, then later decrypted again on runtime or when publishing services. By default, the API Manager uses a relational database for storage. One of the many examples of data that gets stored are the credentials that must be provided when the manager wants to publish an API and makes an authenticated REST call to the gateway.

Data for the API gateway and API manager are stored separately to keep components fully decoupled. For a more detailed overview, please see our http://www.apiman.io/latest/production-guide.html#_architecture_summary[API layer architecture].

Let's swan dive into some code!

=== IDataEncrypter Interface and Data Encryption Classes

The component interface used by apiman to encrypt data (both in the API Manager and in the API Gateway) is called `IDataEncrypter`. This interface provides the structure for the classes that encrypt keys and data, which is done synchronously using AES.

By default, the `DefaultDataEncrypter` class is the encrypter for the gateway. The encrypt and decrypt methods accept a single parameter for the string to be encrypted or decrypted, respectively. If you look at the code, you'll notice that the key is hard coded. For those of us that are looking for a more secure approach, we offer an alternative.

The `AesDataEncrypter` class is a data encrypter that accepts an encrypted secret key. When it is invoked, it expects a configuration object that contains a previously defined encrypted secret key.

At this point you may be wondering how secret keys are obtained. A factory class called `ConfigFactory` is responsible for creating a configuration Map using information from `apiman.properties`. This configuration Map is later passed to `AesDataEncrypter` as a parameter when it is constructed. The secret key included in the configuration Map is then used whenever data is encrypted or decrypted.

== Setting the Gateway to use a Custom Encrypted Secret Key

*We highly recommend that users change the default gateway encryption class* to the more secure `AesDataEncrypter` class. To do so, please follow these steps:


--
{empty}1. Locate and open the `apiman.properties` file.

{empty}2. Uncomment the following lines, located toward the top of the file (around line 10), by removing the hashtag at the beginning of each line:

```properties
apiman.encrypter.type=io.apiman.common.util.crypt.AesDataEncrypter
apiman.encrypter.type.secretKey=
```

{empty}3. Add your encrypted secret key (_the key must be a 16 character string_).

{empty}4. Save and close the file.

{empty}5. $$$ Profit!
--


== Writing Your Own Encryption Plugin

One of the major benefits of working with an open source API management platform, and open source projects in general, is the ability to read and modify the source code to make it work for your business needs. In apiman, we make it easy for you to write your own implementation of the data encrypter by http://www.apiman.io/latest/developer-guide.html#_creating_a_plugin[creating a plugin that encrypts data].

Once your basic plugin is set up, you can then begin working on the Java component of your plugin that contains the functionality.

Every encryption plugin must implement the `IDataEncrypter` interface like this:

```java
public class SuperDataEncrypter implements IDataEncrypter {
/**
* Constructor.
*/
public SuperDataEncrypter(Map<String, String> config) {
thing = config.get("thing"); //$NON-NLS-1$

if (thing == null) {
throw new RuntimeException("Missing configuration property: apiman-manager.config.thing"); //$NON-NLS-1$
}
}
}
```


As you can see, the class is constructed with the configuration Map we discussed above. Once the `SuperDataEncrypter` class is built, the configuration Map is checked for a "thing" key. If it is null, a runtime exception is thrown. Pretty, straightforward so far, right?

Whenever data is stored in a persistent store (either by the API Manager or by the API Gateway), the data encrypter is used to encrypt that data. You can pretty much guess what our next step will be:

```java
public class SuperDataEncrypter implements IDataEncrypter {
/**
* Constructor.
*/
public SuperDataEncrypter(Map<String, String> config) {
thing = config.get("thing"); //$NON-NLS-1$

if (thing == null) {
throw new RuntimeException("Missing configuration property: apiman-manager.config.thing"); //$NON-NLS-1$
}
}


/* (non-Javadoc)
* @see io.apiman.common.util.crypt.IDataEncrypter#encrypt(java.lang.String)
*/
@Override
public String encrypt(String plainText) {
return AesEncrypter.encrypt(secretKey, plainText);
}

/* (non-Javadoc)
* @see io.apiman.common.util.crypt.IDataEncrypter#decrypt(java.lang.String)
*/
@Override
public String decrypt(String encryptedText) {
return AesEncrypter.decrypt(secretKey, encryptedText);
}
}
```

From there, you can use your `SuperDataEncrypter` class to write the functionality you need. For an example of an implementation you can take a look at the `AesDataEncrypter` class we discussed earlier. You should be up and running in no time!

NOTE: If you are kind enough to want to share your plugin with the rest of the apiman community, create a pull request on the https://github.com/apiman/apiman-plugins[apiman plugins repository]. Contributors, please don't forget to write a unit test for any plugin you write (one that actually passes, kthx!).


== Key Takeaways

If your memory is as short-lived as mine, it’s probably best that we do a quick recap. In this article we discussed the importance of securing stored data, and why it should be treated as an essential component of your API security strategy. We then discussed how apiman encrypts and decrypts sensitive data, with a detailed review of the IDataEncrypter interface and the classes that implement it.

For those of us with a guilty security conscience, we went over how to configure the API gateway to use an encrypted key that you provided in the `apiman.properties` file. Because we’re über ambitious, we also took a look at how to write your very own implementation of said `IDataEncrypter` interface and the methods you are required to implement.

As always, we _love_ hearing from you! So, if you have any questions or comments, feel free to leave them below or http://www.apiman.io/latest/chat.html[reach out to us].
1 change: 1 addition & 0 deletions blog/about/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

<script src="http://www.apiman.io/latest/resources/jquery-1.11.1/js/jquery.min.js"></script>
<script src="http://www.apiman.io/latest/resources/bootstrap-3.3.0/js/bootstrap.min.js"></script>
<script id="dsq-count-scr" src="//apiman.disqus.com/count.js" async></script>

<!-- Canonical URL -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

<script src="http://www.apiman.io/latest/resources/jquery-1.11.1/js/jquery.min.js"></script>
<script src="http://www.apiman.io/latest/resources/bootstrap-3.3.0/js/bootstrap.min.js"></script>
<script id="dsq-count-scr" src="//apiman.disqus.com/count.js" async></script>

<!-- Canonical URL -->

Expand Down Expand Up @@ -202,6 +203,12 @@ <h1 style="color: #666; font-weight: bold" class="post-title section-header">Plu












Expand Down Expand Up @@ -522,6 +529,25 @@ <h2 id="conclusion">Conclusion</h2>

</article>

<div id="disqus_thread"></div>
<script>
var disqus_config = function () {
this.page.url = '';
this.page.identifier = '/api-manager/api-gateway/plugins/development/maven/2015/07/24/plugin-components-redux';
};

(function() { // DON'T EDIT BELOW THIS LINE
var d = document, s = d.createElement('script');

s.src = '//apiman.disqus.com/embed.js';

s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript" rel="nofollow">comments powered by Disqus.</a></noscript>


</div>

</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

<script src="http://www.apiman.io/latest/resources/jquery-1.11.1/js/jquery.min.js"></script>
<script src="http://www.apiman.io/latest/resources/bootstrap-3.3.0/js/bootstrap.min.js"></script>
<script id="dsq-count-scr" src="//apiman.disqus.com/count.js" async></script>

<!-- Canonical URL -->

Expand Down Expand Up @@ -85,6 +86,12 @@












Expand Down Expand Up @@ -331,6 +338,12 @@ <h1 style="color: #666; font-weight: bold" class="post-title section-header">Plu












Expand Down Expand Up @@ -656,6 +669,25 @@ <h2 id="conclusion">Conclusion</h2>

</article>

<div id="disqus_thread"></div>
<script>
var disqus_config = function () {
this.page.url = '';
this.page.identifier = '/api-manager/api-gateway/plugins/development/maven/2015/07/24/plugin-components';
};

(function() { // DON'T EDIT BELOW THIS LINE
var d = document, s = d.createElement('script');

s.src = '//apiman.disqus.com/embed.js';

s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript" rel="nofollow">comments powered by Disqus.</a></noscript>


</div>

</div>
Expand Down
26 changes: 26 additions & 0 deletions blog/api-manager/api/ui/metrics/2015/07/06/metrics-redux.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

<script src="http://www.apiman.io/latest/resources/jquery-1.11.1/js/jquery.min.js"></script>
<script src="http://www.apiman.io/latest/resources/bootstrap-3.3.0/js/bootstrap.min.js"></script>
<script id="dsq-count-scr" src="//apiman.disqus.com/count.js" async></script>

<!-- Canonical URL -->

Expand Down Expand Up @@ -214,6 +215,12 @@ <h1 style="color: #666; font-weight: bold" class="post-title section-header">At












Expand Down Expand Up @@ -415,6 +422,25 @@ <h2 id="conclusion">Conclusion</h2>

</article>

<div id="disqus_thread"></div>
<script>
var disqus_config = function () {
this.page.url = '';
this.page.identifier = '/api-manager/api/ui/metrics/2015/07/06/metrics-redux';
};

(function() { // DON'T EDIT BELOW THIS LINE
var d = document, s = d.createElement('script');

s.src = '//apiman.disqus.com/embed.js';

s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript" rel="nofollow">comments powered by Disqus.</a></noscript>


</div>

</div>
Expand Down
Loading