I'm university student and have got a task to do the secure under the requirement "Don't store the whole secret on the server but still able to validate". My scheme is making an RSA key pair on the client, store the public key on the server and throw away the private key. When authentication needed, Server will encrypt some string with stored private key, let the Client make a same key again and decrypt it with the key and send back to server.
(Maybe) Explained as follow
Some data ----Processing----> RSA-1024(or better) PrivateKey + PublicKey
Private key have to be generated and was the same every time
Public key have to be stored on the server and compatible with given private key
The problem is the processing, I want to let the Client generate the same key for every time I want (could use hashed of some data as an input) but I don't know how to config this. Both Private and Public key is still need to compatible with each other.
Strong private key in the device make the application can't be used if user change the device.
I tried to research all along but most says that I have to save the key on the device otherwise generate a new key every time which is not my aiming.
I have already talk to my Project Teacher and this scheme is passed. but I still need more comments if this scheme has any error or if there are any suggestion from you. I'm still wondering if this scheme is better than storing hashed data and keep it for validation or not.
My scheme have to works on Android Client and PHP Server.
Highly thank you for reading and sorry If there is any error in this thread. I'm quite new here but this time I'm quite sure that this thread isn't duplicated.
Related
In my application I want to use Private key which will encrypt password once and decrypt as many times the tool will be run.
Application will run like:
User will encrypt the password using the tool.
Then user will paste that password in properties file.
When next time tool will run it will read that password and decrypt it to login.
Here I am facing problem like, when I encrypt the password I am doing it using another tool just for encryption perpose. So when I try to decrypt it the key is different than key generated. How can I share private key between these two tools..
Thanks..
I think you are confusing symetric and asymetric encryption. When doing symetric encryption you can use the same key. In asymetric encryption you have two keys. A public key with which you can encrypt your passwords, but you can't decrypt them with this key. This is only possible with the private key.
Therefore you don't need to share a key between those tools. Like the name suggests the private key should never leave you system.
You mixed up different things...
When you use a private key to encrypt something you will need the corresponding public key to decrypt.
If you really want to do this then you can put the path to the public key into the properties file also.
What you have described is some symmetric cipher which uses only one key.
Also, as dasblinkenlight noted, make a password decryptable yields some security issues so test if you can design your application different...
Thanks to all of you for your replies,
I am very new in data encryption. Trying it for the first time..
I am working on a tool which is basically run using script. The code will be kept on secured server where very few people have access. Just the concern was the Users do not want to keep password in properties file without encrypting it. So if any one else try to configure properties file they should not be able to figure out the password. As there are there will be three different loging credential will be there for three differnt sources. And respective admins will configure them from the same file.
I found one solution over it.
http://www.code2learn.com/2011/06/encryption-and-decryption-of-data-using.html
Which is best suited solution for my problem...
:)
I think your main concern is sharing the key between applications.
In my opinion, the best way to do this would be to use a Public-Private Keypair. You could distribute the public key and keep your private key safe.
If several apps are used to generate passwords, then use the public key to encrypt.
If one app generates the password and several apps use it then you could encrypt with private key and all your other apps can use their bundled public key to decrypt the password.
Point is, once you have figured out your keypair distribution, you could you either public or private to encrypt or decrypt depending on how the application is designed.
Please refer Beginning Crypto examples for more details on how to create keypair and encrypt/decrypt data.
I need to store a private string key inside of the app. Its value will never change and is set manually in code. I cannot obviously just store it as a String as reverse-engineering method would reveal it, even with obfuscation applied.
How do you suggest I protect this private key?
I though of saving it into a database, but a database can be pulled out of the phone as well.
PS. this key is a special parameter so an important method and it's crucial it stays unknown to anyone! It's not a decrypting key. This string will be used as a parameter to encryption method (md5 or similar) and then a result will be sent to our Internet service.
EDIT
Sorry, for making it so complicated. I thought I could get an answer with as few info as possible.
This app will allow users to send some text to an Internet service which then posts that text to a web site. We need to make sure that the text is sent via Android phone as any web robot script can mimic android phone and post a spam. As captcha-like methods are not welcome on mobile phones, there will be a secret key which will be put through md5 (with some other things) to generate a hash code. This hash will be sent to an Internet service. The Internet service will use the same key to get a md5 result and then compare it to see if the sender is a mobile phone or some robot.
This is really the max I am allowed to say. I hope it is enough.
I'd suggest that you rethink your security architecture. Anything shipped with the app is discoverable. (For instance, Android's license validation library is designed so that a public key is shipped with the app.)
One possibility is for the app to retrieve the key from a server (over a secure socket or https connection). This would obviously require that the app submit to the server some sort of identification/validation (probably based on user input).
If you're using the key for encryption, then take another look at how public key encryption is supposed to work. Your app should have the public key; the internet service can then decrypt with the matching private key.
If you can settle with #Adam's comment, there is at least one solution I know of for persisting a String value on the phone in a... well... persistent manner, meaning that the value will survive a uninstall/re-install of your app (a factory reset would remove it though), yet remain "hidden" for the user (i.e. stored in system private storage, not on the SD-Card).
You can use the system settings content provider to store the value like so:
final String myKey = "verySecretKey";
final String myValue = "verySecretValue";
final boolean isSuccess = System.putString(getContentResolver(), myKey, myValue);
And to retrieve it you can do:
myValue = System.getString(getContentResolver(), myKey);
And yes, on a rooted phone a handy user might get hold of the persisted value, but in that case nothing is holy anymore and #Adam's comment will get valid: You shouldn't store the data on the device.
Okay, I am working on an application and I want to store a file on the user's SD Card, but I want the file encrypted. I've researched several sites that use the DES encryption to encrypt files and data, but I am confused about something. All the examples I'm seen use a line like this:
SecretKey key = KeyGenerator.getInstance("DES").generateKey();
The problem I am having is that I get my key to encrypt and obviously I need the same key to decrypt. But its seems like a paradox because if I store my key in a file or in a database, can't someone get the key and decrypt my file? Maybe I am missing something, but is there a way to generate a key using a supplied pass phrase? And why would someone not want to use a passkey if they must store the generated key somewhere else?
I think there are two cases:
You trust the user - let the key be dependent on some input (password / passphrase). and encrypt / decrypt the data with it.
You don't trust the user - then you're in trouble, you might obfuscate the encryption / decryption algorithm, but as long as the mechanism + key is stored on the device, you will have this problem.
This applies to both symmetric and asymmetric encryption.
First of all, please don't use DES. It has been broken from many years. Use AES instead.
The problem I am having is that I get
my key to encrypt and obviously I need
the same key to decrypt.
If you use symmetric cryptography techniques this is it. Otherwise have a look to asimmetric encryption.
But its seems like a paradox because
if I store my key in a file or in a
database, can't someone get the key
and decrypt my file?
Yes, someone could do it.
Maybe I am missing something, but is there a way to generate a key using a supplied pass phrase?
You don't use a the key using a passphrase. Usually you do the following things:
key generation
encrypt the key generated with a symmetric key derived from a passphrase
And why would someone not want to use
a passkey if they must store the
generated key somewhere else?
There could be several reasons. For example you can store the key in a removable device, and you want simply connect it to your computer for retrieving the key, without entering the passphrase.
Having a passphrase has its disadvantage too: passphrase must be remembered, can be guessed, if it's too long probably you'll write it down (and that's pretty the same thing then storing it in a file )
EDIT:
to generate a key from a password have a look at PBKDF2 (related post).
Yeah, it is possible to use a pass-phrase to encrypt.
But first, dump DES. Use AES-128.
Accept the pass-phrase from the user and and generate the hash using SHA-256 or SHA-512. Trim the hash to 128 bits for AES-128. Refer this post.
Java AES and using my own Key
Use a salt when you can.
Regarding the storage of password part. Store the hash and not the password. This way you can prevent the attacker from generating the key. Ask the user to enter strong password. And don't forget that your salt must be very strong too.
So, in the end, you store only the hash of the password. The password is not stored and the key to decrypt will not be stored(It will be generated at run-time)
Hope it helps.
How to exchange the public key to the client place. i have encrypted a document(text file) using RSA algorithm by using private key and then stored the public key as an java.security.Key object in a file using serialization.I want to know about the integrity of the serialized public key object whether it is safe option to do or any other option available.
A public key is usually just exchanged as a piece of text. It is then imported into a keystore. The exact method of doing is depends on the implementation (I've always used PGP).
I wouldn't expose the key as a serialized form of java.security.Key because it's not really standard. The key in it's simple form is the standard form of interchange.
On exposing the key as a download: it's public, so there's nothing an intruder could do by downloading your key. The only thing that could go wrong is that someone could fake your server and host a different key. Then sign with that key's private key and claim to be you. Of course you could have the same issue if you mailed it to somebody. But then at least you would know who you mailed it to.
The safest approach is to spread the key out-of-bound. Like on a usb stick.
Depending on your cause, I think you can live with the risk.
Joeri has answered on the security aspects - I have nothing to add about that.
The main problem you might have is the serialized representation changing between library versions, which is a potential issue with any use of Java serialization.
Of course there are other ways to do it. The RSA public key should have an industry-standard encoding which you can access using the getEncoded() method. This gives you an array of bytes which you can write to a FileOutputStream. So it's really easy.
Android's security manual says that it is not safe to keep public key (used for Android market) just as a string and it should be hidden/encoded somehow.
Can somebody please provide me with example how it can be done?
(I don't have separate server, so it can not be stored there)
Upd. Believe, this is quite common task related not to Android, but to other apps also.
The relevant text from the page you linked to is this:
Important: To keep your public key safe from malicious users and
hackers, do not embed your public key as an entire literal string.
Instead, construct the string at runtime from pieces or use bit
manipulation (for example, XOR with some other string) to hide the
actual key. The key itself is not secret information, but you do not
want to make it easy for a hacker or malicious user to replace the
public key with another key.
That's pretty much all you need to know. There's no harm in people knowing your public key, the potential harm here is that someone replaces the public key in your program with their own in an effort to divert in-app purchases to their own account.
They're suggesting that you make it more difficult for that attacker by storing the key in separate pieces or XORing the key with some other string. Now, instead of just pasting their key over yours, they have to figure out what transforms you're doing to the string and make their own key fit that pattern. This is more work and might deter casual attackers, but won't prevent someone who is really determined.
If you use the Keytool utility this is all done for you. You'll get a .keystore file on your local computer containing your private key(s) that is encrypted with a password; keep that file and the password secret and you're secure.
http://developer.android.com/guide/publishing/app-signing.html
In fact I believe the Android plugin for Eclipse even does all of this for you automatically.
On the public key, you can hash it and save it as a hash value. Better yet would be to salt the hash value with something you would know when you need to get the hashed value back. May be something like user name, or ESN. Look at android.telephony.TelephonyManager.getDeviceId()