From the archive · 2015
Patient Data Encryption Tool
A desktop tool that encrypted single columns of hospital patient data, decryptable only in an authorised user's browser.
As part of a larger HSE project, I built a tool to encrypt a single column of a CSV file, such as a full name, postal address or medical record number, so that it could later be decrypted in a web browser by someone holding a valid private key.
The data was Patient Administration System (PAS) extracts from every hospital in Ireland. Files ran to millions of rows across several years, the export tools in each hospital didn’t quite follow the CSV standard, and decryption had to work on older HSE hardware. I built it as a Node Webkit application that streamed the files through Node’s crypto APIs.
Encryption
The user picks a CSV file and the column to protect. The tool generates two cryptographically strong 128-bit random strings and runs them through PBKDF2 to make a session key that changes on every run. The column is encrypted with that key using the XXTEA block cipher, chosen because it is fast and runs in a browser.
The session key is then RSA encrypted with a known 1024-bit public key and appended to each encrypted row, so the key travels with the data it protects.
Key management
A master key pair was generated and entrusted to the HSE, and the tool encrypted with the master public key. The encrypted data fed a web reporting and analysis system that was part of Health Atlas Ireland. Each user there had their own authentication bundle holding a copy of the private master key, their hospital group, a UUID and an expiry date, all protected by the user’s password.
Access also depended on where the user was. Records could only be opened from an approved location in the hospital they belonged to, checked by IP address, and only by accounts with the right privileges and roles.
Decryption in the browser
When a user asked to see records, the server checked their location and privileges before releasing the encrypted bundle. The user’s password opened the bundle in the browser, the private key decrypted each session key, and each record was then decrypted with XXTEA. Records sharing a session key were grouped so the expensive RSA step ran once per key.
Everything happened inside the browser. Nothing travelled in clear text, and decrypted data stayed in memory only for the session.