Vigenère – Encrypt All the Things!
This is the story of a service that began its life as a literal water cooler conversation and progressed from conception to a working beta in less than two hours. My coworker and buddy Eli (an administrator working for User Support) and I had just gotten out of an unrelated meeting and were talking about the various nonsense going on in our particular areas when he mentioned that he was having a problem with users inputting PHI (Protected Health Information) into the description field of our ticketing system. This is really less of a problem than it sounds as it was mainly identifiers so that application admins could lookup the patient record that was experiencing the issue, but it’s still PHI and should really be encrypted nonetheless.
The issue is that Cherwell, our ticketing system, does not support encryption natively, so what management was considering was implementing a “policy” and putting notices above the description field stating that PHI was not allowed in the field. As we all know, a policy like that has little chance of actually being followed in the real world for various reasons, the least of which is the fact that users don’t know how to read…
Total elapsed time: 10 minutes.
The second option they had come up with was don’t encrypt the field, but hide it and require the user to click a button before viewing it so at least it’s audited and the PHI is not exposed to people who have no need to see it. Not ideal, but better than nothing.
Anyways, I mentioned that it was unfortunate that Cherwell couldn’t make HTTP requests because he could just offload his encryption functionality to me… Well, as it turns out, Cherwell can actually make HTTP requests, I just wasn’t aware of that… but fortunately Eli was.
Total elapsed time: 25 minutes.
So I went back to my desk, imported “System.Security.Cryptography,” and by the time Eli got back to his (he works in a different building so it took him about 20 minutes to get there), I had a prototype service up and running in Legion that would accept the encryption key, the cleartext, and the audit information and return the randomly generated IV and the ciphertext. And before you get all grumpy, we’re not actually using the Vigenère cipher; the service implements Rijndael 256 (I wanted to call it Caesar, but we already had a service named that and Vigenère was next in line).
Total elapsed time: 45 minutes.
We then spent some time sending raw requests to Vigenère, testing out the encryption and decryption methods which seemed to work perfectly except for the fact that some ciphertext was occasionally being truncated due to restrictions on the query string length, but that was easily remedied.
Total elapsed time: 60 minutes.
The next step was really all on Eli’s end and involved him setting up triggers for the encryption and decryption events, as well as adding fields to the ticked object to store the IV. He then needed to kick off a request to Legion to preform the actual encryption and decryption, which was pretty painless, but we ran into some trouble with Cherwell parsing the response. You see, Legion returns XML, and Cherwell does not have a native XML parser… nor a regex parser (yes, yes… regex + xml == bad, but when you have a nail and don’t have a hammer…). The ultimate solution was rather sketchy, but since the document format is consistent, we were able to apply string manipulation to it to pull out the needed fields.
Total elapsed time: 90 minutes.
There was a little bit more massaging of data and sanity checking in Cherwell, but we got it working. Then we starting throwing all the edge cases we could think of against it to see if anything would stick… but the system worked perfectly.
The only thing left to do was to take some screenshots, write up some documentation, and send it to our bosses to forward to the committee so they could approve of the solution and submit it to testing.
Total elapsed time: 120 minutes.
A few weeks later we went live, and it’s been purring along ever since.