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.
Related
What will be the most secure way in java to Pass username and password encrypted between 2 backend systems written in Java behind the vpn?
The goal will be that if the username and password encrypted being captured by someone, it could never be decrypted.
Theoritically speaking, asymmetric encryption tools are used for transporting confidential data. Every node/client will has a pair of keys that one of them is private and only known by itself, and the other one is public and should be known by everbody that wants to send confidential data to that particular node. The thing is, if a payload data is encrypted with the public key of the client X, it can only be decrypted with the private key of the client X.
Protocols like SSL, TLS, etc. are some widely used implementations of that concept.
assuming you can control both servers in an un-monitored manner(or at least not monitored by the intruder) and could implement any code on both servers then:
you can write your own made up protocol and its encryption algorithms on both systems and use it to share your data between your two systems.
this way the intruder would have no clue what the captured data even is or how to interpret them.
since you said 'Never be decrypted' your protocol could use an encryption key which is already defined on both servers and is not exchanged between them(over a handshake for example) and could use an encryption algorithm which doesn't store any encryption key validation in the transmitted data(like padding or hash etc) and of course shouldn't exchange the encryption algorithm.
it is worth noting that ssl/tls or any other protocol which expose their encryption algorithm and exchange encryption keys used are bad ideas to reach your goal since these protocols are prone to be deciphered if certain portions of their traffic are captured.
The SHA (Secure Hash Algorithm) is one of the popular cryptographic hash functions. A cryptographic hash can be used to make a signature for a text or a data file.
The SHA-256 algorithm generates an almost-unique, fixed-size 256-bit (32-byte) hash. This is a one-way function, so the result cannot be decrypted back to the original value.
Currently, SHA-2 hashing is widely used as it is being considered as the most secure hashing algorithm in the cryptographic arena.
A few library like Guava or Apache commons codec provide the functions.
In your case, I suggest you send the Username in clear text, but send the password use the SHA encrypted, since it cannot be decrypted, in another backend system, you have save the enrypted String somewhere safe like Database, when the password send over, you just need to see the encrypted string match.
This is nice tutorial article talk about SHA in java:
https://www.baeldung.com/sha-256-hashing-java
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.)
I have an Android application that communicates with another java application. For the data encryption i use the javax.crypto library to encrypt and decrypt the data with a pre-shared key.
According to this question it's possible to get the source code from an APK file. So if somebody is able to read the source code of my application, he's also able to read/manipulate the encrypted data.
It's probably true, so is there a way to prevent this (additional measures, other security method)? Don't know if it have extra value but here is my encryption code:
private static String IV = "AAAAAAAAAAAAAAAA";
private static String ENCRYPTION_KEY = "0123456789abcdef";
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec key = new SecretKeySpec(ENCRYPTION_KEY.getBytes("UTF-8"), "AES");
cipher.init(Cipher.ENCRYPT_MODE, key,new IvParameterSpec(IV.getBytes("UTF-8")));
return cipher.doFinal(input.getBytes("UTF-8"));
EDIT:
Communication is send and recieving by NFC. My main issue is, if someone has the key he's able to read and write (abused) information to the other side (the NFC reader)
The pre-shared key is not safe!
For someone with just little java reverse engineering skills it is a job of five minutes to decompile your APK file and extracting the key. Once this has been done your crypto is effectively useless.
The standard approach to fix this is to use a key agreement algorithm. You can for example use the Diffie-Hellman key exchange to quickly and secure generate a common secret between two devices: Wikipedia on Diffie-Hellman
Build a hash from the generated common secret and use this as your AES encryption key for this session is a lot more secure and doesn't take much work.
If NFC is your transport layer you need bidirectional data exchanges for Diffie-Hellman to work. Therefore Android Beam will not be usable for you. You can however do bidirectinal data-transfer using host based card emulation on one phone and reader/writer mode on the other.
Using encryption when transmitting data over NFC is a good idea by the way, also the communication range is limited to some few centimeters, you can still sniff the communication from a few meters distance. NFC doesn't do any encryption for you.
A last word of warning: Cryptography is hard to do in practice. Before you send out anything of value over a cryptographic link please make sure that you have a good understanding of what you do. I recommend reading this book which is a good and practical introduction of cryptography: Bruce Schneider - Cryptography Engineering
I've read about the Adobe CryptoSupport that is now in CQ5.5+, which is meant to provide a utility for encrypting and decrypting data, for example, to store API keys in the JCR more securely.
The JavaDocs or the general Adobe documentation give no details on its implementation, just stating that:
Note that this method and the decrypt(byte[]) method provide full
round trip support:
decrypt(encrypt(plainText)).equals(plainText) == true
Please note,
that calling this method twice on the same plainText does not return
the same cipher text:
encrypt(plainText).equals(encrypt(plainText)) == false
This is reasonably useful, but what it doesn't tell me is how these ciphers are enncrypted to begin with. I've tried encrypting on one CQ instance & decrypting on another, but this doesn't seem to work.
To use this feature with confidence, I'd like to know on what CQ bases its encrypted.
There are two main concerns I have:
How do I know that the service is salted (think that's the correct term) based on something secure? Or if it needs to be configured, how do I do that? (i.e. does it use the equivalent level of security OOTB as a log-in of 'admin/admin'!)
If the encryption is environment specific, does this mean that I cannot encrypt data & then transfer across between servers?
Bundle description in the Felix console states that
The Crypto Support bundle provides a CryptoSupport services which
allows applications to encrypt and decrypt binary and String data.
Encryption is based on the symmetric AES/CBC/PKCS5Padding (AES
algorithm, CBC mode with PKCS5 padding) from the RSA JSafe libary.
Key is randomly generated during the first start of the Adobe Granite Crypto Support bundle and then saved as /etc/key/master property. It is per-instance by design and I don't think it's a good idea to move this key between CQ installations. Actually, Adobe says it's a good idea to move key between author and publish instances.
Answering your questions:
you don't need to worry about configuring the service as it's done automatically during the first bundle activation,
you can move encrypted data from one instance to another as long as you also move the key.
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.