Hi Herman,
i just wrote a class to encrypt / decrypt Strings like User / Password.
Note that using this class doesn't ensure absolute security because
someone can decompile your java code to get the key. But this class
ensures that no one can find out the password by simply looking in the
xml file.
This is my Crypt class:
public class Crypt {
private javax.crypto.spec.SecretKeySpec keySpec;
private byte[] key;
private String algorithm;
/** Creates a new instance of Crypt */
public Crypt(byte[] key, String algorithm) {
this.key = key;
this.algorithm = algorithm;
this.keySpec = new javax.crypto.spec.SecretKeySpec(this.key,
this.algorithm);
}
/** Encrypts the give String to an array of bytes */
public byte[] encryptString(String text) {
try {
javax.crypto.Cipher cipher =
javax.crypto.Cipher.getInstance(this.algorithm);
cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, this.keySpec);
return cipher.doFinal(text.getBytes());
} catch (Exception e) {
return null;
}
}
/** Decrypts the given array of bytes to a String */
public String decryptString(byte[] b) {
try {
javax.crypto.Cipher cipher =
javax.crypto.Cipher.getInstance(this.algorithm);
cipher.init(javax.crypto.Cipher.DECRYPT_MODE, this.keySpec);
return new String(cipher.doFinal(b));
} catch (Exception e) {
return null;
}
}
/** Encrypts the given String to a hex representation of the array
of bytes */
public String encryptHexString(String text) {
return toHex(encryptString(text));
}
/** Decrypts the given hex representation of the array of bytes to
a String */
public String decryptHexString(String text) {
return decryptString(toByteArray(text));
}
/** Converts the given array of bytes to a hex String */
private String toHex(byte[] buf) {
String res = "";
for (int i=0; i<buf.length; i++) {
int b = buf[i];
if (b<0) {
res = res.concat("-");
b = -b;
}
if (b<16) {
res = res.concat("0");
}
res = res.concat(Integer.toHexString(b).toUpperCase());
}
return res;
}
/** Converts the given hex String to an array of bytes */
private byte[] toByteArray(String hex) {
java.util.Vector res = new java.util.Vector();
String part;
int pos = 0;
int len = 0;
while (pos<hex.length()) {
len = ((hex.substring(pos,pos+1).equals("-")) ? 3 : 2);
part = hex.substring(pos,pos+len);
pos += len;
int test = Integer.parseInt(part,16);
res.add(new Byte((byte)test));
}
if (res.size()>0) {
byte[] b = new byte[res.size()];
for (int i=0; i<res.size(); i++) {
Byte a = (Byte)res.elementAt(i);
b[i] = a.byteValue();
}
return b;
} else {
return null;
}
}
}
Then you can easily use this class to encrypt / decrypt Strings. Choose
a 8 Byte key as you like:
public class Test {
private static final byte[] key =
{(byte)0x01,(byte)0xE3,(byte)0xA2,(byte)0x19,(byte)0x59,(byte)0xBD,(byte)0xEE,(byte)0xAB};
public static void main(String[] args) {
Crypt crypt = new Crypt(key,"DES");
String toEncrypt = "This is a text to encrypt";
String encrypted = crypt.encryptHexString(toEncrypt);
String decrypted = crypt.decryptHexString(encrypted);
System.out.println(toEncrypt);
System.out.println(encrypted);
System.out.println(decrypted);
}
}
cu
Dirk
> Is there an easy way to encrypt/decrypt a String value. What I want to
> do is to save an password in a XML file, but that should be encrypte
> before it would be saved.
> Has anyone a suggestion?
>
> Thanks.
Michael Amling - 05 Mar 2004 13:39 GMT
> Hi Herman,
>
[quoted text clipped - 117 lines]
> }
> }
Normally you'd also want to specify a mode, such as CBC or CTR, and
an initialization vector, and provide for message authentication. I
assume that you're thinking that since, with the key hardcoded, it's not
going to be secure anyway, that you can skip normal practice.
I don't think I've ever seen a hex representation where each byte
could have its own sign. Here are some more efficient and more compact
implementations.
/** Converts the given array of bytes to a hex String */
public static String toHex(byte[] buf) {
char[] cbf=new char[buf.length*2];
for (int jj=0, kk=0; jj<buf.length) jj++) {
cbf[kk++]="0123456789ABCDEF".charAt((buf[jj]>>4) & 0x0F);
cbf[kk++]="0123456789ABCDEF".charAt(buf[jj] & 0x0F);
}
return new String(cbf);
}
/** Converts a valid hex String to an array of bytes */
public static byte[] toByteArray(String hex) {
byte[] result=new byte[hex.length()/2];
for (int jj=0, kk=0; jj<result.length; jj++) {
result[jj]=(byte)(
("0123456789ABCDEF".indexOf(hex.charAt(kk++))<<4)+
"0123456789ABCDEF".indexOf(hex.charAt(kk++)));
}
}
>> Is there an easy way to encrypt/decrypt a String value. What I want
>> to do is to save an password in a XML file, but that should be
>> encrypte before it would be saved.
>> Has anyone a suggestion?
--Mike Amling
Dirk Michaelsen - 08 Mar 2004 08:18 GMT
Hi Michael
thank you for your input. As you suggested it is not very important for
my application to be absolute secure. The Coding of the Password is only
done to prevent that someone reads the account data from the properties
file. With enough criminal energy one can decrypt any code.
I put your methods into my program, after correcting some errors. Now it
works like a charme:
/** Converts the given array of bytes to a hex String */
public static String toHex(byte[] buf) {
char[] cbf=new char[buf.length*2];
for (int jj=0, kk=0; jj<buf.length; jj++) {
cbf[kk++]="0123456789ABCDEF".charAt((buf[jj]>>4) & 0x0F);
cbf[kk++]="0123456789ABCDEF".charAt(buf[jj] & 0x0F);
}
return new String(cbf);
}
/** Converts a valid hex String to an array of bytes */
public static byte[] toByteArray(String hex) {
byte[] result=new byte[hex.length()/2];
for (int jj=0, kk=0; jj<result.length; jj++) {
result[jj]=(byte)(
("0123456789ABCDEF".indexOf(hex.charAt(kk++))<<4)+
"0123456789ABCDEF".indexOf(hex.charAt(kk++)));
}
return result;
}
cu
Dirk
> Normally you'd also want to specify a mode, such as CBC or CTR, and an
> initialization vector, and provide for message authentication. I assume
[quoted text clipped - 31 lines]
>
> --Mike Amling