vphomealone
vphomealone

Reputation: 163

URL Encryption in Java

What is the best way to encrypt an URL with parameters in Java?

Upvotes: 8

Views: 28080

Answers (7)

Internet Friend
Internet Friend

Reputation: 1072

Are you sure you don't mean URL encode?

Encoding is available through java.net.URLEncoder.encode.

Upvotes: 0

Dónal Boyle
Dónal Boyle

Reputation: 3079

The standard way to encrypt HTTP traffic is to use SSL. However, even over HTTPS, the URL and any parameters in it (i.e. a GET request) will be sent in the clear. You would need to use SSL and do a POST request to properly encrypt your data.

As pointed out in the comments parameters will be encrypted no matter what HTTP method you use, as long as you use an SSL connection.

Upvotes: 0

Denis
Denis

Reputation: 1239

Unfortunatelly almost noting is simple in java :-) , for this simple and usual task I wasnt able to find a prepared library, I ended up writing this (this was the source):

 import java.net.URLDecoder;
import java.net.URLEncoder;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEParameterSpec;

/**
 * An easy to use class to encrypt and decrypt a string. Just call the simplest
 * constructor and the needed methods.
 * 
 */

public class StringEncryptor {
private Cipher encryptCipher;
private Cipher decryptCipher;
private sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
private sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();

final private String charset = "UTF-8";
final private String defaultEncryptionPassword = "PAOSIDUFHQWER98234QWE378AHASDF93HASDF9238HAJSDF923";
final private byte[] defaultSalt = {

(byte) 0xa3, (byte) 0x21, (byte) 0x24, (byte) 0x2c,

(byte) 0xf2, (byte) 0xd2, (byte) 0x3e, (byte) 0x19 };

/**
 * The simplest constructor which will use a default password and salt to
 * encode the string.
 * 
 * @throws SecurityException
 */
public StringEncryptor() throws SecurityException {
    setupEncryptor(defaultEncryptionPassword, defaultSalt);
}

/**
 * Dynamic constructor to give own key and salt to it which going to be used
 * to encrypt and then decrypt the given string.
 * 
 * @param encryptionPassword
 * @param salt
 */
public StringEncryptor(String encryptionPassword, byte[] salt) {
    setupEncryptor(encryptionPassword, salt);
}

public void init(char[] pass, byte[] salt, int iterations) throws SecurityException {
    try {
        PBEParameterSpec ps = new javax.crypto.spec.PBEParameterSpec(salt, 20);

        SecretKeyFactory kf = SecretKeyFactory.getInstance("PBEWithMD5AndDES");

        SecretKey k = kf.generateSecret(new javax.crypto.spec.PBEKeySpec(pass));

        encryptCipher = Cipher.getInstance("PBEWithMD5AndDES/CBC/PKCS5Padding");

        encryptCipher.init(Cipher.ENCRYPT_MODE, k, ps);

        decryptCipher = Cipher.getInstance("PBEWithMD5AndDES/CBC/PKCS5Padding");

        decryptCipher.init(Cipher.DECRYPT_MODE, k, ps);
    } catch (Exception e) {
        throw new SecurityException("Could not initialize CryptoLibrary: " + e.getMessage());
    }
}

/**
 * 
 * method to decrypt a string.
 * 
 * @param str
 *            Description of the Parameter
 * 
 * @return String the encrypted string.
 * 
 * @exception SecurityException
 *                Description of the Exception
 */

public synchronized String encrypt(String str) throws SecurityException {
    try {

        byte[] utf8 = str.getBytes(charset);

        byte[] enc = encryptCipher.doFinal(utf8);

        return URLEncoder.encode(encoder.encode(enc),charset);
    }

    catch (Exception e)

    {
        throw new SecurityException("Could not encrypt: " + e.getMessage());
    }
}

/**
 * 
 * method to encrypting a string.
 * 
 * @param str
 *            Description of the Parameter
 * 
 * @return String the encrypted string.
 * 
 * @exception SecurityException
 *                Description of the Exception
 */

public synchronized String decrypt(String str) throws SecurityException {
    try {

        byte[] dec = decoder.decodeBuffer(URLDecoder.decode(str,charset));
        byte[] utf8 = decryptCipher.doFinal(dec);

        return new String(utf8, charset);

    } catch (Exception e) {
        throw new SecurityException("Could not decrypt: " + e.getMessage());
    }
}

private void setupEncryptor(String defaultEncryptionPassword, byte[] salt) {

    java.security.Security.addProvider(new com.sun.crypto.provider.SunJCE());

    char[] pass = defaultEncryptionPassword.toCharArray();

    int iterations = 3;

    init(pass, salt, iterations);
}

}

Upvotes: 2

Oli
Oli

Reputation: 1782

If you really can't use SSL, I'd suggest a pre-shared key approach and adding a random iv.

You can use any decent symmetric encryption method ex. AES using a pre-shared key you're communicating out of band (email, phone etc.).

Then you generate a random initialization vector and encrypt your string with this iv and the key. Finally you concatenate your cipher text and the iv and send this as your parameter. The iv can be communicated in the clear without any risk.

Upvotes: 1

Alexander
Alexander

Reputation: 9370

It depends on your threat model. For example, if you want to protect the parameters sent by your Java app to your server from an attacker who has access to the communication channel, you should consider communicating with the server via TLS/SSL (i.e., HTTPS in your case) and the likes. If you want to protect the parameters from an attacker who has access to the machine where your Java client app runs, then you're in deeper trouble.

Upvotes: 1

Neall
Neall

Reputation: 27134

The only way to do this is to use SSL/TLS (https). If you use plain old HTTP, the URL will definitely be sent in the clear.

Upvotes: 3

l_39217_l
l_39217_l

Reputation: 2110

java security api(http://java.sun.com/javase/technologies/security/) + url encoding

Upvotes: 1

Related Questions