I'm creating an Android application, that at first needed to be able to transmit data to the server securely. So I thought of RSA.
I would send the public key to the user, let him do what he must, then receive back and decrypt via private. That is all fine.
But now it seems, that there should also be some sort of encryption to the other side. Meaning, there should be means of encrypting a message and sending it to the user, and allow only the specific user be able to read it.
This smells like having 2 pairs of keys, and sending public key from one pair and private key from the other to the user, and keeping the rest to the server.
I have looked at symmetric keys, but they somehow seem less secure to me.
Am I missing something, or is this common? I'm somewhat new to the whole cryptography scene.
The usual advice applies: use HTTPS, don't try to invent a secure messaging protocol. You will most likely fail. If you absolutely need to this, the usual way is to use RSA keys to encrypt symmetric session keys and encrypt your data with those. Also note that the size of data you can encrypt with an RSA key is limited by the key size (1024, 2048, etc. bits).For two way communication, each party needs to have the other party's public key. So it goes something like this:
Alice hands her public key (RSA) securely to Bob (see below)
Bob hand his public key (RSA) securely to Alice
When Bob wants to communicate with Alice, he generates a session key (say, a 256-bit AES key), then uses her public key to encrypt it.
Bob sends the encrypted session key to Alice.
Bob uses the session key (AES) to encrypt the message, and sends it to Alice.
Alice uses her private key (RSA) to decrypt the session key (AES).
Alice decrypts the message from Bob using the session key (AES).
Reverse the roles of Alice in Bob in steps 3 to 7 for communicating the other way.
But of course, if you send a public key to someone, how can they be sure that it is actually your key, not mine? If you don't hand it in person and show your photo ID, this is far from trivial.
Then, you need some way to verify that the (encrypted) message from Bob has not been modified (you can cut in half, and it will still be valid and decryptable; there are other, more sophisticated attacks, of course).
So just convince whoever you need to convince to use HTTPS or some other established protocol, and don't try to re-invent the wheel.
This smells like having 2 pairs of keys, and sending public key from one pair and private key from the other to the user, and keeping the rest to the server.
This is not how public key infrastructure works. Each of you generate your own keypairs, and exchange public keys.
Server's public key is used by client to encrypt data to server and verify signatures on messages received from server.
Server's private key is used by the server to decrypt messages from the client and to sign messages going to the client.
The reverse actions for the client's keypair are the same.
Related
I want to send sensitive data from one app to another.
I use Intent and send data via Bundle. Now, I am supposed to use an encryption algorithm to encrypt the data to send and parallelly the receiver app will decrypt the data.
Which algorithm is best suited for the mobile platform?
I have gone through RSA documents suggests that it is not suggested for long text encryption.
I have seen the algorithm uses a random key generation method which will cause an issue in my case as both the app need to share the same key to encrypt and decrypt.
I have gone through RSA documents suggests that it is not suggested for long text encryption.
true
Depending in the key length, e. g. 2048 key with pkcs#1.5 padding is intended to encrypt maximum if 245 bytes. Some implementation frameworks enforce even less (144 bytes,..)
I have seen the algorithm uses a random key generation method which will cause an issue in my case as both the app need to share the same key to encrypt and decrypt.
Actually - it's a combination of the both ways what is commonly used. see hybrid cryptosystem
Basically - each app has its own keypair and the apps share the public keys of the destination parties. You can use a random key for data encryption and rsa to encrypt the data key. Then feel safe to use Intend and Bundle to move the encrypted data and encrypted key.
It may be a good baseline to start with.
Edit:
I need to send data from my one app(A) to another(B). So, A will encrypt the data and will send the data to B with encryption (key is generated in app A).
If you send an encryption key (let's call it data key) along data in plain, anyone intercepting the traffic (intent or bundle) would be able to decrypt the data. So that's where the RSA comes into the game. You can encrypt the data key the way only B can decrypt it
Now B has to decrypt the data. If the new code of key generation will be written in app B then it will create different key and hence will not be able to decrypt....
Try to search and learn how an asymmetric cipher (RSA) works. The full description is outside scope of the question, you may ask another one what is not clear in it.
Basically - app B needs to create a keypair (public and private key). The public key is used for encryption, the private key is for decryption. A needs to get the public key of B to encrypt the data key.
How you get the public key from B to A is up to you (shared storage, configure in an app, ..)
You want to pass encrypted data without sharing a common secret between apps, then RSA is a way to go.
I have an firebase application which consist of group chats.
and I want to implement end-to-end encryption.
So far I've tried to below strategy to
1) Create an secret key (AES) for group to encrypt/decrypt texts
2) Created RSA key for individual users
3) encrypting AES secret key using user's public RSA key and decrypting using private key
I want to keep the AES key on server by encryting and then, allow user to fetch that AES key thru API and use to encrypt/decrypt messages
AESKEY (encrypted) ---> (decrypt to plain text(this is the challenge - how to decrypt this on server side) ----> encrypt using public key of user) ----> send to user
The challenge I am facing is, as I have encrypted the AESKEY on Server using my public key, but when the user requests the AESKEY, my application may be offline so eventually the user will not get the decrypted AESKEY
I was thinking to keep AESKEY on server by encrypting and on user's request I perform encryption/decryption task on server itself.
It is quite unreasonable to do this, as it's a lot simpler and not less safe to only encrypt the message itself with the other parties' public key, and then they can all decrypt it themselves with their private keys.
I should develop an phonegap application. I need to encrypt my requests to the server side and then decrypt.
HTTPS is not a solution, because I need to sign requests to be sure that the data is not fake. I can use any async cryptography (the app will generate private/public keys and will send public key to the server). But this way I need to keep my private key on the device.
The question is: how I can keep private key on the device securely?
I can use sqlclipher (to encrypt my local SQLite DB) and integrate it into my phonegap app. Great, but here I have to keep secret key for database :)
var db = window.sqlitePlugin.openDatabase({name: "DB", key: "secret1"});
Any one who have access to the phone can get this secret key. So here I have the same issue:)
Please, give me any suggestions.
Thanks!
p.s. app for iOS and Android
You have to differentiate between encryption and authentication.
First, I suggest to use https to encrypt your messages and transfer them securely.
Second, I suggest to use HMAC for authentication of your messages. It basically works like this:
Generate a secret string known to your app and the server at compile time. You store this secret directly in the source code of your app so it is never transmitted to or from the server. This might be the main difference to your private/public key approach: You compile the secret right into your app instead of writing it later in some user accessible storage. "Right into your app" means in the case of Phonegap NOT in your HTML/JS files but in the native source code! You have to bridge the accessor to javascript if necessary.
Set a user id (=key; long, random!) in your app when the user starts your app for the first time. If you want to authenticate your users, you probably have some kind of login/password mechanism. (Store the user id as well as an HMAC generated from the user id and the shared secret on the device. Every time you read the user id, check it against the hash to be sure that the user id was not spoofed.)
In your App
Include a user id in every message.
Include a timestamp in every message.
Calculate the HMAC hash from a string put together from the message, the server address, the request URI, and the shared secret.
Include the hash value in your request header.
On the server side
Check if the timestamp is valid, e. g. not older than 2 minutes or so. This prevents replay attacks (at least after 2 minutes).
Check in your database if the user id is valid.
Calculate the HMAC hash from a string put together from the message, the server address, the request URI, and the shared secret. Including the request URI prevents people to send the same valid request to another URI on your server; e. g. in REST environments it is a big difference if you send the same DELETE request to /comment/1 or /user/1.
Compare it to the hash value submitted in your header, they have to be equal.
If any check fails, send an error. Otherwise send the response.
There is a chance of getting the shared secret and information about the way how you calculate the HMAC hash by decompiling your source code. I see no way to avoid this risk. ...without diving deeper into native development:
iOS Keychain
https://developer.apple.com/library/ios/documentation/Security/Conceptual/keychainServConcepts/iPhoneTasks/iPhoneTasks.html
Android security features
http://developer.android.com/training/articles/security-tips.html
By default, PhoneGap does not provide the feature of encryption on its own. Devices based on iOs and Android(above Gingerbread version) support full-disk encryption. But this is not available to PhoneGap/Cordova developers.
From the wiki:
PhoneGap is generally limited to the security features of the platform
on which it is running.
Refer to https://github.com/phonegap/phonegap/wiki/Platform-Security
For some JS based solution, give a try at http://code.google.com/p/crypto-js/
I am making an Android application which involves two phones exchanging a lot of data over several minutes. I would like this communication to be encrypted and have been researching the various cryptographic options available. It seems like the most suited would be a hybrid algorithm, that uses asymmetric encryption (like RSA) to exchange a session key and a symmetric algo (like AES) to actually encrypt / decrypt the data.
From what I know of hybrid encryption, every packet sent between the two devices should use a new session key, which is embedded within the packet (encrypted with the other party's public key) to facilitate decryption at the other end.
To save CPU, I am considering using just one session key which is exchanged using RSA, and then encrypting / decrypting all data using this key, so that I can save on costly RSA operations. However, I understand that this is not recommended? Can someone please confirm this and tell me how I should proceed?
EDIT:
Thought I would add some more information here -
The communication protocol is completely custom and my own. Data is sent in unencrypted UDP packets, with a lot of metadata and an encrypted payload. So that rules out using regular SSL / TLS.
Also, for every session I generate new private and public keys, exchange the public keys and then use that to exchange a session key which is used in AES. I am using 2048-bit RSA and 256-bit AES. This, AFAIK, is more than enough and probably overkill for most communication. I will admit that my knowledge of cryptography isn't excellent, but I'm reading and learning as much as I can to make this as secure as possible.
Nothing 'wrong' with it, just a security tradeoff. The longer the keys, the longer the session can be. You're trying to keep the key long enough, or the session short enough, or a mixture, such that key compromise is infeasible in the time available. You also need to consider whether it's OK to leak the data for the entire session if a key gets cracked, or whether you need the extra security of a new key per message or whatever.
Why not use a l long live TLS/SSL session? This does pretty much exactly what you want, efficiently and doesn't require you to write tricky crypto code you will almost certainly get wrong.
In general, almost any crypto system I am aware of generates one symmetric key for the entire session and uses that for the duration. This is what TLS does and what SSH does. I believe this is what IPSEC does. There is no problem with this from a cryptographic point of view assuming you use a sane cipher like AES have sufficiently large IVs/Counters/Nonces such that they don't repeat.
The one worry about using this is that if your secret key leaks, you loose all the data in the session. However, if your secret key can leak, so too can your private key. At which point an attacker could decrypt previous session keys and get the data even if you followed the one key per packet mode.
I'm creating an application that encrypts data with a key that is created each time the user logs into the app. However, there are times when data will be received via a BroadcastReceiver that needs encrypting, but the user is not logged in and so the encryption key is not available.
Security is pretty important and so using a key stored in code to encrypt the data until the user next logs in is out of the question as is storing one in the applications DB despite it being within the apps sandbox.
I've been searching through the Android docs and get hints of APIs to address this situation but have not yet come up with a definitive solution.
Anyone know of the usual solution to this problem? I expect it crops up quite a lot in software development.
Let's see...
Setup: Create an RSA keypair. Encrypt the private key. Store the public key unencrypted.
Broadcast received: Generate a random AES-128 key/IV. Encrypt the key with the RSA public key. Encrypt the payoad with the key/iv. Store the encrypted key, iv, and encrypted payload.
Login: Decrypt the private key. Use the private key to decrypt the AES key. Use the AES key to decrypt the payload.
And since this was the first idea that came to mind, I can't vouch for its security properties.
I'm also not sure what security properties you're looking for — what attacks are you attempting to defend against? Why couldn't an attacker just intercept the broadcast directly? Aren't you worried about it lingering around in other processes' memory?
Two ideas:
The BroadcastReceiver get the encrypted data, do the login by stored credentials and get the key to decrypt the data.
You BR just store the encrypted data and inform the user, so the user logs in to get the decrypted data.
I don't know what your app does, so its just a guess what could be possible...