001: /*
002: * Lucane - a collaborative platform
003: * Copyright (C) 2002 Vincent Fiack <vfiack@mail15.com>
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: */
019: package org.lucane.common.crypto;
020:
021: import java.security.*;
022:
023: /**
024: * Handles Base64 enconding.
025: * Inspired by the Jakarta Project
026: */
027: public class Base64 {
028: /**
029: * Encodes a byte array
030: *
031: * @param raw the bytes to encode
032: * @return the encoded string
033: */
034: public static String encode(byte[] raw) {
035: int encLen = ((raw.length + 2) / 3) * 4;
036: StringBuffer encoded = new StringBuffer(encLen);
037: int len3 = (raw.length / 3) * 3;
038:
039: for (int i = 0; i < len3; i += 3)
040: encoded.append(encodeFullBlock(raw, i));
041:
042: if (len3 < raw.length)
043: encoded.append(encodeBlock(raw, len3));
044:
045: return encoded.toString();
046: }
047:
048: /**
049: * Decode a string
050: *
051: * @param base64 the string to decode
052: * @return the corresponding byte array
053: */
054: public static byte[] decode(String base64) {
055: try {
056: int pad = 0;
057:
058: for (int i = base64.length() - 1; (i > 0)
059: && (base64.charAt(i) == '='); i--)
060: pad++;
061:
062: int length = base64.length() / 4 * 3 - pad;
063: byte[] raw = new byte[length];
064:
065: for (int i = 0, rawIndex = 0; i < base64.length(); i += 4, rawIndex += 3) {
066: int block = (getValue(base64.charAt(i)) << 18)
067: + (getValue(base64.charAt(i + 1)) << 12)
068: + (getValue(base64.charAt(i + 2)) << 6)
069: + (getValue(base64.charAt(i + 3)));
070:
071: for (int j = 2; j >= 0; j--) {
072: if (rawIndex + j < raw.length)
073: raw[rawIndex + j] = (byte) (block & 0xff);
074:
075: block >>= 8;
076: }
077: }
078:
079: return raw;
080: } catch (Exception e) {
081: return new byte[0];
082: }
083: }
084:
085: /**
086: * Encode a Key in base64
087: *
088: * @param key the Key to encode
089: * @return the encoded String
090: */
091: public static String encodeKey(Key key) {
092: return encode(key.getEncoded());
093: }
094:
095: private static char[] encodeBlock(byte[] raw, int offset) {
096: int block = 0;
097: int slack = raw.length - offset - 1;
098: int end = (slack >= 2) ? 2 : slack;
099:
100: for (int i = 0; i < 3; i++) {
101:
102: byte b = (offset + i < raw.length) ? raw[offset + i] : 0;
103: int neuter = (b < 0) ? b + 256 : b;
104: block <<= 8;
105: block += neuter;
106: }
107:
108: char[] base64 = new char[4];
109:
110: for (int i = 3; i >= 0; i--) {
111:
112: int sixBit = block & 0x3f;
113: base64[i] = getChar(sixBit);
114: block >>= 6;
115: }
116:
117: if (slack < 1)
118: base64[2] = '=';
119:
120: if (slack < 2)
121: base64[3] = '=';
122:
123: return base64;
124: }
125:
126: private static char[] encodeFullBlock(byte[] raw, int offset) {
127: int block = 0;
128:
129: for (int i = 0; i < 3; i++) {
130: block <<= 8;
131: block += (0xff & raw[offset + i]);
132: }
133:
134: block = ((raw[offset] & 0xff) << 16)
135: + ((raw[offset + 1] & 0xff) << 8)
136: + (raw[offset + 2] & 0xff);
137:
138: char[] base64 = new char[4];
139:
140: for (int i = 3; i >= 0; i--) {
141: int sixBit = block & 0x3f;
142: base64[i] = getChar(sixBit);
143: block >>= 6;
144: }
145:
146: return base64;
147: }
148:
149: private static char getChar(int sixBit) {
150: if ((sixBit >= 0) && (sixBit < 26))
151: return (char) ('A' + sixBit);
152:
153: if ((sixBit >= 26) && (sixBit < 52))
154: return (char) ('a' + (sixBit - 26));
155:
156: if ((sixBit >= 52) && (sixBit < 62))
157: return (char) ('0' + (sixBit - 52));
158:
159: if (sixBit == 62)
160: return '+';
161:
162: if (sixBit == 63)
163: return '/';
164:
165: return '?';
166: }
167:
168: private static int getValue(char c) {
169: if ((c >= 'A') && (c <= 'Z'))
170: return c - 'A';
171:
172: if ((c >= 'a') && (c <= 'z'))
173: return c - 'a' + 26;
174:
175: if ((c >= '0') && (c <= '9'))
176: return c - '0' + 52;
177:
178: if (c == '+')
179: return 62;
180:
181: if (c == '/')
182: return 63;
183:
184: if (c == '=')
185: return 0;
186:
187: return -1;
188: }
189: }
|