01: // Copyright (C) 2003,2004,2005 by Object Mentor, Inc. All rights reserved.
02: // Released under the terms of the GNU General Public License version 2 or later.
03: package fitnesse.authentication;
04:
05: import fitnesse.components.Base64;
06:
07: public class HashingCipher implements PasswordCipher {
08: private static final int repetitions = 3;
09:
10: private static final String theMagicLock = // A Peom by Yeats.
11: "Like a long-leggedfly upon the stream\n"
12: + "His mind moves upon silence.";
13:
14: public String encrypt(String value) {
15: byte[] crypted = repeatEncryption(theMagicLock.getBytes(),
16: value.getBytes());
17: byte[] squeezed = fillToSize(crypted, 15);
18: byte[] encoded = Base64.encode(squeezed);
19:
20: return new String(encoded);
21: }
22:
23: private byte[] repeatEncryption(byte[] lock, byte[] key) {
24: for (int i = 0; i < repetitions; i++)
25: lock = encrypt(lock, key);
26:
27: return lock;
28: }
29:
30: private byte[] encrypt(byte[] lock, byte[] key) {
31: int keyIndex = 0;
32: for (int i = 0; i < lock.length; i++) {
33: byte lockByte = lock[i];
34: byte keyByte = key[keyIndex++];
35: lock[i] = (byte) (lockByte + keyByte);
36: if (keyIndex == key.length)
37: keyIndex = 0;
38: }
39:
40: return lock;
41: }
42:
43: public byte[] fillToSize(byte[] input, int size) {
44: byte[] bytes = new byte[size];
45: int inputLength = input.length;
46: int inputIndex = 0;
47: int outputIndex = 0;
48: if (inputLength <= size) {
49: while (outputIndex < size) {
50: bytes[outputIndex++] = input[inputIndex++];
51: if (inputIndex == inputLength)
52: inputIndex = 0;
53: }
54: } else {
55: while (inputIndex < inputLength) {
56: byte currentByte = bytes[outputIndex];
57: bytes[outputIndex++] = (byte) (currentByte + input[inputIndex++]);
58: if (outputIndex == size)
59: outputIndex = 0;
60: }
61: }
62:
63: return bytes;
64: }
65: }
|