PubNub is a HIPAA-compliant instant messaging platform that supports message and file encryption using AES-256-CBC.
The provided encryption is flawed, it drops half of the entropy from the encrpytion key, effectively half of the encrpytion key is constant.
The getKey function does an SHA-256 on the provided key string to make it the required 256bit (32byte) length for the AES-256. Then it's hex encoded, doubling the length in bytes then trimmed to 32 bytes. Due to hex encoding and trimming half of the bits in the key are always the same for every encoded message or file.
https://github.com/pubnub/javascript/blob/master/src/crypto/modules/web.js#L70
async getKey(key) {
const bKey = Buffer.from(key);
const abHash = await crypto.subtle.digest('SHA-256', bKey.buffer);
const abKey = Buffer.from(Buffer.from(abHash).toString('hex').slice(0, 32), 'utf8').buffer;
return crypto.subtle.importKey('raw', abKey, 'AES-CBC', true, ['encrypt', 'decrypt']);
}
Hi!
Thank you for your reply.
Half of the encryption key that end up being passed to the AES algorithm are known and it's exactly the same for every single message encrypted by PubNub's client libraries.
Yes, it's a problem in the PubNub client side libraries published on github.
Note that half of the encryption key is known and the random initialization vector is not a secret, it's saved along with the encrypted message.
I'm not a lawyer nor an encryption expert, but there are concerns you should consider in relation to HIPAA.
As far as I understand HIPAA requires at least AES-128. I cannot assess how PubNub's encrypt functionality relates to that, provided that it's technically AES-256, but half of the encryption key is constant.
Please note that PubNub's partners may unable to fix the issue for themselves, as PubNub's BAA may no longer cover HIPAA compliance should they chose to use different encryption.