Android, General, Java, Windows

Cross-platform encryption

April 25th, 2010 | Comment?

One of the main goals I’ve always had for Cryptnos has been as much cross-platform compatibility as possible. As far as I can tell, so long as you always use the same text encoding on every platform, Cryptnos always generates the same password, regardless of whether you are using .NET, Android, or Java. That’s our core functionality right there, so needless to say I’m happy about this one.

However, as of this writing, there’s one place where cross-platform compatibility has eluded me: the import/export files. The raw data storage isn’t an issue; that almost has to be done in a platform dependent way. .NET uses the Windows registry, Android uses a database, and the Java version will likely use an encrypted text file. But I’ve always wanted to be able to export parameters from one platform and import them into another. That would have made the implementation and testing of the Android so much easier if I could have just imported the parameters I generated in .NET. Alas, this wasn’t the case, and I had to type every single one of them in and verify the results in both places. Currently, each platform exports their parameters in a different way, so you cannot import that data into a different platform.

For those who have never coded with encryption, it’s not a pretty place. It’s never as simple as “Here’s the plain text data, here’s the encryption key, and here’s the algorithm.  Put them all together and get the encrypted text.” You have to use the same key generation classes on every platform, or at least ones that are equivalent. You have to make sure your padding scheme is the same everywhere. If you get one little thing wrong, the data you encrypt on one platform won’t come out right on the other platform and you’ll get binary garbage. And of course, the API developers never make it easy for you, as the class and method names are never the same from one platform to another.

Fortunately, the problem is somewhat mitigated by the fact that Android uses Java as its primary development language. Thus, if I can find a way to encrypt something in Java that can be decrypted in .NET and vice versa, I’ll kill three birds with two stones. Sadly, that prize has eluded me so far, primarily for the reason mentioned above: .NET and Java name everything differently, and I have to figure out exactly what combination of options in both places will yield the same result.

Ideally, I want to use as many built-in classes as possible. If I can find a way to do what I want with the tools that are already built into each language, I keep the code size down and make it easier to port elsewhere. Failing that, however, I do have the fall-back of using the Legion of the Bouncy Castle Crypto API, which I’ve already dipped into for a few of our cryptographic hashes. I’d rather not use this option, however, as I’d like to keep the code base as small as possible, especially for the Android app. Adding additional library code that effectively duplicates functionality that already exists in the core library just makes the program bigger than it needs to be. That said, it does give me a common API that should be compatible between both .NET and Java.

If there is anyone out there who has experience coding cross-platform encryption between .NET and Java, especially using password-based AES, I’d love to hear from you. I’ve been doing research and found a few promising leads, but nothing has worked straight out of the box and it’s going to take a while to experiment and find out what’s not working.

UPDATE APRIL 28, 2010: Well, I think I answered my own question. I quickly discovered a number of important facts:

  1. Trying to implement something as critically temperamental as encryption using to very different and very distinct APIs is not fun. .NET and Java do encryption in very different ways, and they don’t mesh well together. Similar sounding classes do things differently in each API, and things that end up do doing the same thing are usually named differently, making it hard to find a common ground. Thus, I’m ditching the totally native implementations and going with the Bouncy Castle API. It may make the applications larger, but at least they share the same API now and they work basically the same.
  2. That said, using the “same” API ported to two different platforms doesn’t necessarily guarantee 100% compatibility. For example, I found one method on BC’s .NET code that was deprecated, only to find there was no comparable method like it in the Java API. Thus, I’m stuck using the deprecated .NET method to remain compatible with the Java method and hoping BC doesn’t break that in their next update. (Bad form there, BC.)
  3. It helps to pay attention to which classes you use. There are a lot of similarly named classes, and it’s easy to get them confused. I kept on getting error after error, only to find out I was using two different classes, one on Java and a different one on .NET, at a critical point in the process. Seems like Programming 101, I know, but even old seasoned dogs like myself make boneheaded newbie mistakes every now and then.

And now, the point of the update: Thanks to this research and Bouncy Castle’s API, I have successfully encrypted data on Google Android and decrypted it with .NET, and vice versa. That was the most critical part of making cross-platform compatible export files work. So the call for help has been withdrawn, but thanks to anyone out there listening. (At least I hope all those requests to this site aren’t coming from my own IPs.) Look for future updates soon that result from this discovery.

Tags: , , , , ,


You can skip to the end and leave a response. Pinging is currently not allowed.

Be nice. Keep it clean. Stay on topic. No spam.

You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

You must be logged in to post a comment.