So after CodingHorror's fun with encryption and the thrashing comments, we are reconsidering doing our own encryption.
In this case, we need to pass some information that identifies a user to a 3rd party service which will then call back to a service on our website with the information plus a hash.
The 2nd service looks up info on that user and then passes it back to the 3rd party service.
We want to encrypt this user information going into the 3rd party service and decrypt it after it comes out. So it is not a long lived encryption.
On the coding horror article, Coda Hale recommended BouncyCastle and a high level abstraction in the library to do the encryption specific to a particular need.
My problem is that the BouncyCastle namespaces are huge and the documentation is non-existant. Can anyone point me to this high level abstraction library? (Or another option besides BouncyCastle?)
Installation of Bouncy Castle for use in TomEE itself is done in two steps: Add the Bouncy Castle provider jar to the $JAVA_HOME/jre/lib/ext directory. Create a Bouncy Castle provider entry in the $JAVA_HOME/jre/lib/security/java. security file.
The Bouncy Castle Crypto APIs are looked after by an Australian Charity, the Legion of the Bouncy Castle Inc., which looks after the care and feeding of the Bouncy Castle APIs. Help us keep this effort Free, Open Source, and Maintained!
Bouncy Castle is a Java library that complements the default Java Cryptographic Extension (JCE), and it provides more cipher suites and algorithms than the default JCE provided by Sun. In addition to that, Bouncy Castle has lots of utilities for reading arcane formats like PEM and ASN.
To get the latest Bouncy Castle release, navigate to http://www.bouncycastle.org/latest_releases.html. Select the latest release, or the release that corresponds to your version of Java. Download the signed JAR file. Stop all the IBM processes and Lawson.
High level abstraction? I suppose the highest level abstractions in the Bouncy Castle library would include:
I am mostly familiar with the Java version of the library. Perhaps this code snippet will offer you a high enough abstraction for your purposes (example is using AES-256 encryption):
public byte[] encryptAES256(byte[] input, byte[] key) throws InvalidCipherTextException { assert key.length == 32; // 32 bytes == 256 bits CipherParameters cipherParameters = new KeyParameter(key); /* * A full list of BlockCiphers can be found at http://www.bouncycastle.org/docs/docs1.6/org/bouncycastle/crypto/BlockCipher.html */ BlockCipher blockCipher = new AESEngine(); /* * Paddings available (http://www.bouncycastle.org/docs/docs1.6/org/bouncycastle/crypto/paddings/BlockCipherPadding.html): * - ISO10126d2Padding * - ISO7816d4Padding * - PKCS7Padding * - TBCPadding * - X923Padding * - ZeroBytePadding */ BlockCipherPadding blockCipherPadding = new ZeroBytePadding(); BufferedBlockCipher bufferedBlockCipher = new PaddedBufferedBlockCipher(blockCipher, blockCipherPadding); return encrypt(input, bufferedBlockCipher, cipherParameters); } public byte[] encrypt(byte[] input, BufferedBlockCipher bufferedBlockCipher, CipherParameters cipherParameters) throws InvalidCipherTextException { boolean forEncryption = true; return process(input, bufferedBlockCipher, cipherParameters, forEncryption); } public byte[] decrypt(byte[] input, BufferedBlockCipher bufferedBlockCipher, CipherParameters cipherParameters) throws InvalidCipherTextException { boolean forEncryption = false; return process(input, bufferedBlockCipher, cipherParameters, forEncryption); } public byte[] process(byte[] input, BufferedBlockCipher bufferedBlockCipher, CipherParameters cipherParameters, boolean forEncryption) throws InvalidCipherTextException { bufferedBlockCipher.init(forEncryption, cipherParameters); int inputOffset = 0; int inputLength = input.length; int maximumOutputLength = bufferedBlockCipher.getOutputSize(inputLength); byte[] output = new byte[maximumOutputLength]; int outputOffset = 0; int outputLength = 0; int bytesProcessed; bytesProcessed = bufferedBlockCipher.processBytes( input, inputOffset, inputLength, output, outputOffset ); outputOffset += bytesProcessed; outputLength += bytesProcessed; bytesProcessed = bufferedBlockCipher.doFinal(output, outputOffset); outputOffset += bytesProcessed; outputLength += bytesProcessed; if (outputLength == output.length) { return output; } else { byte[] truncatedOutput = new byte[outputLength]; System.arraycopy( output, 0, truncatedOutput, 0, outputLength ); return truncatedOutput; } }
Edit: Whoops, I just read the article you linked to. It sounds like he is talking about even higher level abstractions than I thought (e.g., "send a confidential message"). I am afraid I don't quite understand what he is getting at.
Assuming that you write your application in Java I'd recommend that you don't use a specific provider, but that you develop your application on top of Sun's JCE (Java Cryptography Extension). Doing so can make you independent of any underlying providers, I.e., you can switch providers easily as long as you use ciphers that are widely implemented. It does give you a certain level of abstraction as you don't have to know all the details of the implementations and may protect you a little from using the wrong classes (e.g. such as using raw encryption without proper padding etc) Furthermore, Sun provides a decent amount of documentation and code samples.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With