1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44:
45: import ;
46: import ;
47: import ;
48:
49:
54: public final class SRP
55: {
56:
57: private static final HashMap algorithms = new HashMap();
58: private static final byte COLON = (byte) 0x3A;
59:
60: private IMessageDigest mda;
61:
62:
63: private SRP(final IMessageDigest mda)
64: {
65: super();
66:
67: this.mda = mda;
68: }
69:
70:
76: public static synchronized SRP instance(String mdName)
77: {
78: if (mdName != null)
79: mdName = mdName.trim().toLowerCase();
80: if (mdName == null || mdName.equals(""))
81: mdName = SRPRegistry.SRP_DEFAULT_DIGEST_NAME;
82: SRP result = (SRP) algorithms.get(mdName);
83: if (result == null)
84: {
85: final IMessageDigest mda = HashFactory.getInstance(mdName);
86: result = new SRP(mda);
87: algorithms.put(mdName, result);
88: }
89: return result;
90: }
91:
92: private static final byte[] xor(final byte[] b1, final byte[] b2,
93: final int length)
94: {
95: final byte[] result = new byte[length];
96: for (int i = 0; i < length; ++i)
97: result[i] = (byte)(b1[i] ^ b2[i]);
98: return result;
99: }
100:
101:
102: public String getAlgorithm()
103: {
104: return mda.name();
105: }
106:
107:
116: public IMessageDigest newDigest()
117: {
118: return (IMessageDigest) mda.clone();
119: }
120:
121:
129: public byte[] digest(final byte[] src)
130: {
131: final IMessageDigest hash = (IMessageDigest) mda.clone();
132: hash.update(src, 0, src.length);
133: return hash.digest();
134: }
135:
136:
146: public byte[] digest(final String src) throws UnsupportedEncodingException
147: {
148: return digest(src.getBytes("US-ASCII"));
149: }
150:
151:
161: public byte[] xor(final byte[] a, final byte[] b)
162: {
163: return xor(a, b, mda.hashSize());
164: }
165:
166: public byte[] generateM1(final BigInteger N, final BigInteger g,
167: final String U, final byte[] s, final BigInteger A,
168: final BigInteger B, final byte[] K, final String I,
169: final String L, final byte[] cn, final byte[] cCB)
170: throws UnsupportedEncodingException
171: {
172: final IMessageDigest hash = (IMessageDigest) mda.clone();
173: byte[] b;
174: b = xor(digest(Util.trim(N)), digest(Util.trim(g)));
175: hash.update(b, 0, b.length);
176: b = digest(U);
177: hash.update(b, 0, b.length);
178: hash.update(s, 0, s.length);
179: b = Util.trim(A);
180: hash.update(b, 0, b.length);
181: b = Util.trim(B);
182: hash.update(b, 0, b.length);
183: hash.update(K, 0, K.length);
184: b = digest(I);
185: hash.update(b, 0, b.length);
186: b = digest(L);
187: hash.update(b, 0, b.length);
188: hash.update(cn, 0, cn.length);
189: hash.update(cCB, 0, cCB.length);
190: return hash.digest();
191: }
192:
193: public byte[] generateM2(final BigInteger A, final byte[] M1, final byte[] K,
194: final String U, final String I, final String o,
195: final byte[] sid, final int ttl, final byte[] cIV,
196: final byte[] sIV, final byte[] sCB)
197: throws UnsupportedEncodingException
198: {
199: final IMessageDigest hash = (IMessageDigest) mda.clone();
200: byte[] b;
201: b = Util.trim(A);
202: hash.update(b, 0, b.length);
203: hash.update(M1, 0, M1.length);
204: hash.update(K, 0, K.length);
205: b = digest(U);
206: hash.update(b, 0, b.length);
207: b = digest(I);
208: hash.update(b, 0, b.length);
209: b = digest(o);
210: hash.update(b, 0, b.length);
211: hash.update(sid, 0, sid.length);
212: hash.update((byte)(ttl >>> 24));
213: hash.update((byte)(ttl >>> 16));
214: hash.update((byte)(ttl >>> 8));
215: hash.update((byte) ttl);
216: hash.update(cIV, 0, cIV.length);
217: hash.update(sIV, 0, sIV.length);
218: hash.update(sCB, 0, sCB.length);
219: return hash.digest();
220: }
221:
222: public byte[] generateKn(final byte[] K, final byte[] cn, final byte[] sn)
223: {
224: final IMessageDigest hash = (IMessageDigest) mda.clone();
225: hash.update(K, 0, K.length);
226: hash.update(cn, 0, cn.length);
227: hash.update(sn, 0, sn.length);
228: return hash.digest();
229: }
230:
231: public byte[] computeX(final byte[] s, final String user,
232: final String password)
233: throws UnsupportedEncodingException
234: {
235: return computeX(s, user.getBytes("US-ASCII"), password.getBytes("US-ASCII"));
236: }
237:
238: public byte[] computeX(final byte[] s, final String user, final byte[] p)
239: throws UnsupportedEncodingException
240: {
241: return computeX(s, user.getBytes("US-ASCII"), p);
242: }
243:
244: private byte[] computeX(final byte[] s, final byte[] user, final byte[] p)
245: {
246: final IMessageDigest hash = (IMessageDigest) mda.clone();
247: hash.update(user, 0, user.length);
248: hash.update(COLON);
249: hash.update(p, 0, p.length);
250: final byte[] up = hash.digest();
251: hash.update(s, 0, s.length);
252: hash.update(up, 0, up.length);
253: return hash.digest();
254: }
255: }