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.
Related
Im new here, so please correct me on anything!
I was assigned to do a basic java program where i register and authenticate users, storing the username and the password in a .txt file. The password is stored as an MD5 hash. Also, i needed to make another program to try brute-forcing the .txt file to find the passwords, and measure the time needed to do so.
i managed to do that(suffering a bit), and the last step is to find and implement a way to reduce the chances of this brute-forcing to work. I searched a lot about it, and apart from people saying to use another safer method of storing passwords, the only thing i found useful(which i heard of before so i searched for it) was using salts, Which i know that they are concatenated within the password before hashing, and then both hash and salt are stored.
But i dont think this would work in this occasion, as the salt would also be stored in the .txt file, thus, even taking longer due to the bigger possible range of combinations, i could still do a brute force where i try a combination and add the salt in the .txt to it, then hash it and compare to the hash stored in the .txt.
Is this a viable way to make the brute force harder(at least in this assignment, for learning purposes) as it takes more time, or is there any other methods to do so?
thanks in advance!
first of all. md5-Hash is deprecated. Please use sha256 or sha512 instead.
The salt should not stored inside the text file. It is a config parameter of your programm.
Now, you can use your secret salt and the password to generate the hash.
hashedPw = sha256(salt + password)
This avoids that an attacker can retrieve the original password from look it up in an lookup table. (https://crackstation.net/)
Additionally you can encrypt your passwords with AES-Algorithm.
My question is how does camel pgp actually work and if my deduction is correct at all, I'm not a java programmer so please note that some of the following text might make no sense.
Does it encrypt the payload with a symmetric key, then encrypts the symmetric key with a public key and sends both to the destination (e.g. ftp server) which then decrypts the symmetric key (session key) and then decrypts the payload with it ? Or does it encrypt the payload with pub key and thats it ? Besides, is any of the keys generated every message ? In other words, lets say we have 20 files in a directory, camel processes them one by one, does this mean that the symmetric key will be generated 20 times or it's only generated once and then reused?
I am trying to find out the best solution to encrypt the messages, it seems it's sufficient to use a symmetric key only (AES) as I can transfer it through a safe channel once and that's it, however the implementation appears to be painful in comparison to PGP (I have to implement a Java tool to generate, save to file and load AES keys, play with initialization vector, HMAC etc.), but on the other hand if the latter creates a different key each time it would be inefficient in my case.
In OpenPGP, you've got two choices, Apache Camel allows both of them:
Hybrid Cryptography
A session key (a new one generated each time) is encrypted using public/private (asymmetric) cryptography. This session key is then used for encrypting the actual information using symmetric cryptography.
This approach combines the advantages of public/private and symmetric cryptography: it enables the advanced key management features of OpenPGP, but does not suffer from the enormous costs of encrypting large amounts of data using public/private key cryptography.
Generating new, random session keys each time is very cheap, as those are mostly a random block of data, and do not involve complex calculations as for public/private key pairs.
Using GnuPG (and probably all other implementations), this approach is used by default when using gpg --encrypt. If you specify the recipient's public key, and no passphrase, you will be using this approach.
Symmetric Encryption
OpenPGP also allows directly generating the session key from a passphrase, which is directly used for symmetric encryption. This disables OpenPGP's key management features. Direct symmetric encryption is rarely used with OpenPGP, but might be handy sometimes.
Using GnuPG, this is achieved by calling gpg --symmetric. If you encrypt (and do not sign), but are asked for a passphrase, you will probably be using symmetric cryptography.
In OpenPGP, public/private key cryptography is never used to encrypt input directly.
I have a UI to add/edit password .These passwords are encrypted using Blowfish in CBC mode and it worked fine but during decryption it required a IV (it threw a parameter missing exception.)
I have used the cipher class while initiating the cipher so this would have taken care of the IV while encrypting.
So my doubt is,
should the IV be same for both encryption and decryption? I read on some pages that while decryption if we use an incorrect IV the first block will be incorrect but the remaining blocks would be correct .Can you explain on this?
IF the IV (in case of encryption and decryption using the same IV) be saved should it be saved as a plain object or encrypted along with the password using some delimiter ?Which will be safer?
Thanks in advance.
Yes, the IV should be the same for encryption/decryption. In CBC, if I recall properly, errors will cascade down the blocks. So the whole message will be wrong if you use the wrong IV.
The IV can be stored in plaintext. If you try and store it encrypted, you'll end up needing to store the IV used to encrypt the IV...
However, it is generally considered a bad practice to store passwords in an encrypted form. If someone were to retrieve you database, they'd only need to find one key to retrieve all the passwords.
The recommended way to store passwords is to use a hash function multiple times, also known as a PBKDF (password based key derivation function), either based on a plain hash or on a hmac function. See the OWASP password storage cheatsheet.
There are primitives for this in java, see the example on this page. (Search for Use a Password Hashing Algorithm and scroll down to the java implementation.)
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 am currently making an app that will need to save sensitive data in J2ME, either in RMS or using LWUIT's storage class. (For example username and password)
How secure is such an implementation, and what are the steps to take in order to make sure the data is secure and not vulnerable to theft?
RMS is not encrypted - an attacker can easily read off any data. You'll need to encrypt the data - I recommend the Bouncycastle AES provider, but the Java AES provider also works (although it isn't as efficient, and you'll need to enable 256-bit keys on it). See the accepted answer to this question for some example code, I don't recommend changing anything in the code without asking StackOverflow or another good Q&A site first (it's very easy to incorrectly use encryption libraries); the code uses the Java crypto provider, to use the Bouncycastle provider use Cipher.getInstance("AES/CBC/PKCS7Padding", new BouncyCastleProvider()) after you import the Bouncycastle library. Important to note is that the code generates a Keyspec spec from a char[] password - the user will need to enter this password at least once per session in order for you to decrypt the data (you can't store the password on the device, that would defeat the purpose of encrypting the data). Also important is that you'll need to use the same IV (initialization vector) in the encryption and decryption phases; this IV should be unique to each record that you're encrypting (e.g. when you encrypt foo.txt then use a different IV than when you encrypt bar.txt), but it does not need to be secret (you can store it in plaintext alongside the encrypted file). As an added precaution, wipe the char[] password when you're done with it.