I'm trying to build my own layer of encryption on top of our bluetooth communication. We can't use bonding because of some specific features we need to support. I'm a beginner when it comes to encryption, and so I wanted to run this by someone with more experience. Please look over my planned approach and point out any flaws or improvements:
- Communication is between an iPhone and a bluetooth peripheral. At the start of any connection, the iPhone will generate a random public/private key pair. The public key will be sent to the bluetooth device.
- The bluetooth device will generate a random symmetric key, encrypt it using the iPhone's public key and send it back to the iPhone.
- All future communication will now be performed using the symmetric key for encryption/decryption.
- A security passkey that is generated once for the bluetooth device and used to identify an authorized user is encrypted and sent from the iOS device to the bluetooth device. If the passkey is wrong, the connection is killed. If it is correct, the iOS device now has full access to the bluetooth device via encrypted packet communication. Each new connection will have a new private/public key pair and a new symmetric key.
Because packets are maximum 20 bytes and data rate is around 1200 bytes/second, I plan on encrypting packets using AES256 CTR encryption, as this has the advantage of the encrypted data being the same length as the original data.
Are there some flaws to my approach that I'm not aware of? Are there flaws with my plan to use CTR so the encrypted data is the same length as the original? Is there a better approach to accomplish what I want?
I have a few questions about my specific use case.
I only need to keep the security passkey that is transmitted at the beginning of communications secret, as without that, an attacker wouldn't be able to do any sort of replay attack since new security keys are generated each new connection session. Is this flawed thinking?
Using Diffie-Hellman to generate a symmetric key, then using a stream cipher (CTR) to encrypt communication, would this be secure? Each packet would be encrypted with a new counter value (initialization vector) that would not be reused for the session, which would also be sent with the encrypted packet for decryption on the other end. My understanding is that this method would be perfectly secure as long as I never used the same initialization vector to encrypt two different packets. Is this correct thinking? My main purpose in wanting to use a stream cipher is so my encrypted data length is the same as the unencrypted data length.
Due to point 1 above, is it possible for me to safely get away with using the same initialization vector for all packets encrypted for the entire session, as the next session will have completely different symmetric keys, or will doing this open my protocol up to being decoded by an attacker, enabling them to aquire the passkey mentioned in point 1?
Based on comments by Thomas M. DuBuisson, I see that there are several issues with my approach that I hadn't thought of previously. One major issue being I need to make sure I have a solid random number generator on the bluetooth device. In light of the points he made, and after doing more research on how to securely exchange keys with a limited resource device, I thought of another approach that might be easier with the available resources, and I hope a little more secure. Sorry for my lack of experience in this area, but I'm trying to learn what I can and hopefully not make any stupid mistakes.