KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > maverick > crypto > publickey > Rsa


1 /*
2  * SSL-Explorer
3  *
4  * Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */

19             
20 package com.maverick.crypto.publickey;
21
22 import java.io.IOException JavaDoc;
23
24 import java.math.BigInteger JavaDoc;
25 import com.maverick.crypto.security.SecureRandom;
26
27 public final class Rsa {
28
29   private static BigInteger JavaDoc ONE = BigInteger.valueOf(1);
30
31   public static BigInteger JavaDoc doPrivateCrt(BigInteger JavaDoc input,
32                                         BigInteger JavaDoc privateExponent,
33                                         BigInteger JavaDoc primeP, BigInteger JavaDoc primeQ,
34                                         BigInteger JavaDoc crtCoefficient) {
35     return doPrivateCrt(input,
36                         primeP, primeQ,
37                         getPrimeExponent(privateExponent, primeP),
38                         getPrimeExponent(privateExponent, primeQ),
39                         crtCoefficient);
40   }
41
42   public static BigInteger JavaDoc doPrivateCrt(BigInteger JavaDoc input,
43                                         BigInteger JavaDoc p, BigInteger JavaDoc q,
44                                         BigInteger JavaDoc dP,
45                                         BigInteger JavaDoc dQ,
46                                         BigInteger JavaDoc qInv) {
47     if (!qInv.equals(q.modInverse(p))) {
48       BigInteger JavaDoc t = p;
49       p = q;
50       q = t;
51       t = dP;
52       dP = dQ;
53       dQ = t;
54     }
55
56     BigInteger JavaDoc s_1 = input.modPow(dP, p);
57     BigInteger JavaDoc s_2 = input.modPow(dQ, q);
58     BigInteger JavaDoc h = qInv.multiply(s_1.subtract(s_2)).mod(p);
59     return s_2.add(h.multiply(q));
60
61   }
62
63   public static BigInteger JavaDoc getPrimeExponent(BigInteger JavaDoc privateExponent,
64                                             BigInteger JavaDoc prime) {
65     BigInteger JavaDoc pe = prime.subtract(ONE);
66     return privateExponent.mod(pe);
67   }
68
69   public static BigInteger JavaDoc padPKCS1(BigInteger JavaDoc input, int type,
70                                     int padLen) throws
71                                     IllegalStateException JavaDoc {
72     BigInteger JavaDoc result;
73     BigInteger JavaDoc rndInt;
74     int inByteLen = (input.bitLength() + 7) / 8;
75
76     if (inByteLen > padLen - 11) {
77       throw new IllegalStateException JavaDoc("PKCS1 failed to pad input! "
78                             + "input=" + String.valueOf(inByteLen)
79                             + " padding=" + String.valueOf(padLen));
80     }
81
82     byte[] padBytes = new byte[ (padLen - inByteLen - 3) + 1];
83     padBytes[0] = 0;
84
85     for (int i = 1; i < (padLen - inByteLen - 3 + 1); i++) {
86       if (type == 0x01) {
87         padBytes[i] = (byte) 0xff;
88       }
89       else {
90         byte[] b = new byte[1];
91         do {
92           SecureRandom.getInstance().nextBytes(b);
93         }
94         while (b[0] == 0);
95         padBytes[i] = b[0];
96       }
97     }
98
99     rndInt = new BigInteger JavaDoc(1, padBytes);
100     rndInt = rndInt.shiftLeft( (inByteLen + 1) * 8);
101     result = BigInteger.valueOf(type);
102     result = result.shiftLeft( (padLen - 2) * 8);
103     result = result.or(rndInt);
104     result = result.or(input);
105
106     return result;
107   }
108
109   public static BigInteger JavaDoc removePKCS1(BigInteger JavaDoc input, int type) throws
110                                         IllegalStateException JavaDoc {
111     byte[] strip = input.toByteArray();
112     byte[] val;
113     int i;
114
115     if (strip[0] != type) {
116       throw new IllegalStateException JavaDoc("PKCS1 padding type " +
117                             type + " is not valid");
118     }
119
120     for (i = 1; i < strip.length; i++) {
121       if (strip[i] == 0) {
122         break;
123       }
124       if (type == 0x01 && strip[i] != (byte) 0xff) {
125         throw new IllegalStateException JavaDoc("Corrupt data found in expected PKSC1 padding");
126       }
127     }
128
129     if (i == strip.length) {
130       throw new IllegalStateException JavaDoc("Corrupt data found in expected PKSC1 padding");
131     }
132
133     val = new byte[strip.length - i];
134     System.arraycopy(strip, i, val, 0, val.length);
135     return new BigInteger JavaDoc(1, val);
136   }
137
138   public static RsaPrivateCrtKey generateKey(int bits, SecureRandom secRand) {
139     return generateKey(bits, BigInteger.valueOf(0x10001L), secRand);
140   }
141
142   public static RsaPrivateCrtKey generateKey(int bits, BigInteger JavaDoc e,
143                                              SecureRandom secRand) {
144     BigInteger JavaDoc p = null;
145     BigInteger JavaDoc q = null;
146     BigInteger JavaDoc t = null;
147     BigInteger JavaDoc phi = null;
148     BigInteger JavaDoc d = null;
149     BigInteger JavaDoc u = null;
150     BigInteger JavaDoc n = null;
151     boolean finished = false;
152     BigInteger JavaDoc ONE = BigInteger.valueOf(1);
153
154     int pbits = (bits + 1) / 2;
155     int qbits = bits - pbits;
156
157     while (!finished) {
158       p = new BigInteger JavaDoc(pbits, 80, secRand);
159       q = new BigInteger JavaDoc(qbits, 80, secRand);
160
161       if (p.compareTo(q) == 0) {
162         continue;
163       }
164       else if (p.compareTo(q) < 0) {
165         t = q;
166         q = p;
167         p = t;
168       }
169
170       if (!p.isProbablePrime(25))
171         continue;
172
173       if(!q.isProbablePrime(25))
174         continue;
175
176       t = p.gcd(q);
177       if (t.compareTo(ONE) != 0) {
178         continue;
179       }
180
181       n = p.multiply(q);
182
183       if (n.bitLength() != bits) {
184         continue;
185       }
186
187       phi = p.subtract(ONE).multiply(q.subtract(ONE));
188       d = e.modInverse(phi);
189       u = q.modInverse(p);
190
191       finished = true;
192     }
193
194     return new RsaPrivateCrtKey(n, e, d, p, q,
195                                 Rsa.getPrimeExponent(d, p),
196                                 Rsa.getPrimeExponent(d, q),
197                                 u);
198
199
200   }
201
202   public static BigInteger JavaDoc doPublic(BigInteger JavaDoc input, BigInteger JavaDoc modulus,
203                                     BigInteger JavaDoc publicExponent) {
204     return input.modPow(publicExponent, modulus);
205   }
206
207   public static BigInteger JavaDoc doPrivate(BigInteger JavaDoc input, BigInteger JavaDoc modulus,
208                                      BigInteger JavaDoc privateExponent) {
209     return doPublic(input, modulus, privateExponent);
210   }
211
212 }
213
Popular Tags