blob: 5ad39741b13bba58bafe30c4fc906ad4056d8737 [file] [log] [blame]
package org.eclipse.core.internal.runtime;
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
import java.security.MessageDigest;
import java.security.SecureRandom;
/**
* <P>Encrypts or decrypts a sequence of bytes. The bytes are decrypted
* by supplying the same password that was given when the bytes were
* encrypted.
* <P>Here is an example showing how to encrypt and then decrypt the
* string "Hello, world!" using the password "music":
* <pre>
* String password = "music";
* byte[] data = "Hello, world!".getBytes("UTF8");
*
* // Encrypt
* Cipher cipher = new Cipher(ENCRYPT_MODE, password);
* byte[] encrypted = cipher.update(data);
*
* // Decrypt
* cipher = new Cipher(DECRYPT_MODE, password);
* byte[] decrypted = cipher.update(encrypted);
* </pre>
*/
public class Cipher {
public static final int DECRYPT_MODE = -1;
public static final int ENCRYPT_MODE = 1;
private int mode = 0;
private String password = null;
private SecureRandom secureRandom = null;
/**
* Initializes the cipher with the given mode and password. This method
* must be called first (before any encryption of decryption takes
* place) to specify whether the cipher should be in encrypt or decrypt
* mode and to set the password.
*
* @param mode
* @param password
*/
public Cipher (int mode, String password){
this.mode = mode;
this.password = password;
this.secureRandom = null;
}
/**
* Encrypts or decrypts (depending on which mode the cipher is in) the
* given data and returns the result.
*
* @param data
* @return the result of encrypting or decrypting the given data
*/
public byte[] cipher(byte[] data) throws Exception {
return transform(data, 0, data.length, mode);
}
/**
* Encrypts or decrypts (depending on which mode the cipher is in) the
* given data and returns the result.
*
* @param data the byte array containg the given data
* @param off the index of the first byte in the given byte array
* to be transformed
* @param len the index after the last byte in the given byte array
* to be transformed
* @return the result of encrypting or decrypting the given data
*/
public byte[] cipher(byte[] data, int off, int len) throws Exception {
return transform(data, off, len, mode);
}
/**
* Encrypts or decrypts (depending on which mode the cipher is in) the
* given byte and returns the result.
*
* @param datum the given byte
* @return the result of encrypting or decrypting the given byte
*/
public byte cipher(byte datum) throws Exception {
byte[] data = { datum };
return cipher(data)[0];
}
private byte[] getSeed() throws Exception {
MessageDigest messageDigest = MessageDigest.getInstance("SHA");
return messageDigest.digest(password.getBytes("UTF8"));
}
private byte[] nextRandom(int length) throws Exception {
if (secureRandom == null) {
secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(getSeed());
}
byte[] nextRandom = new byte[length];
secureRandom.nextBytes(nextRandom);
return nextRandom;
}
private byte[] transform(byte[] data, int off, int len, int mode) throws Exception {
byte[] result = nextRandom(len);
for (int i = 0; i < len; ++i) {
result[i] = (byte) (data[i + off] + mode * result[i]);
}
return result;
}
}