1 /* |
|
2 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. |
|
8 * |
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
12 * version 2 for more details (a copy is included in the LICENSE file that |
|
13 * accompanied this code). |
|
14 * |
|
15 * You should have received a copy of the GNU General Public License version |
|
16 * 2 along with this work; if not, write to the Free Software Foundation, |
|
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
18 * |
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
20 * or visit www.oracle.com if you need additional information or have any |
|
21 * questions. |
|
22 */ |
|
23 |
|
24 package sun.security.rsa; |
|
25 |
|
26 import java.math.BigInteger; |
|
27 |
|
28 import java.security.*; |
|
29 import java.security.spec.AlgorithmParameterSpec; |
|
30 import java.security.spec.RSAKeyGenParameterSpec; |
|
31 |
|
32 import sun.security.jca.JCAUtil; |
|
33 import sun.security.x509.AlgorithmId; |
|
34 import static sun.security.rsa.RSAUtil.KeyType; |
|
35 |
|
36 /** |
|
37 * Fake RSA keypair generation. |
|
38 */ |
|
39 public abstract class RSAKeyPairGenerator extends KeyPairGeneratorSpi { |
|
40 |
|
41 // public exponent to use |
|
42 private BigInteger publicExponent; |
|
43 |
|
44 // size of the key to generate, >= RSAKeyFactory.MIN_MODLEN |
|
45 private int keySize; |
|
46 |
|
47 private final KeyType type; |
|
48 private AlgorithmId rsaId; |
|
49 |
|
50 RSAKeyPairGenerator(KeyType type, int defKeySize) { |
|
51 this.type = type; |
|
52 // initialize to default in case the app does not call initialize() |
|
53 initialize(defKeySize, null); |
|
54 } |
|
55 |
|
56 // initialize the generator. See JCA doc |
|
57 public void initialize(int keySize, SecureRandom random) { |
|
58 try { |
|
59 initialize(new RSAKeyGenParameterSpec(keySize, |
|
60 RSAKeyGenParameterSpec.F4), random); |
|
61 } catch (InvalidAlgorithmParameterException iape) { |
|
62 throw new InvalidParameterException(iape.getMessage()); |
|
63 } |
|
64 } |
|
65 |
|
66 // second initialize method. See JCA doc. |
|
67 public void initialize(AlgorithmParameterSpec params, SecureRandom random) |
|
68 throws InvalidAlgorithmParameterException { |
|
69 if (params instanceof RSAKeyGenParameterSpec == false) { |
|
70 throw new InvalidAlgorithmParameterException |
|
71 ("Params must be instance of RSAKeyGenParameterSpec"); |
|
72 } |
|
73 |
|
74 RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec)params; |
|
75 int tmpKeySize = rsaSpec.getKeysize(); |
|
76 BigInteger tmpPublicExponent = rsaSpec.getPublicExponent(); |
|
77 AlgorithmParameterSpec tmpParams = rsaSpec.getKeyParams(); |
|
78 |
|
79 if (tmpPublicExponent == null) { |
|
80 tmpPublicExponent = RSAKeyGenParameterSpec.F4; |
|
81 } else { |
|
82 if (tmpPublicExponent.compareTo(RSAKeyGenParameterSpec.F0) < 0) { |
|
83 throw new InvalidAlgorithmParameterException |
|
84 ("Public exponent must be 3 or larger"); |
|
85 } |
|
86 if (tmpPublicExponent.bitLength() > tmpKeySize) { |
|
87 throw new InvalidAlgorithmParameterException |
|
88 ("Public exponent must be smaller than key size"); |
|
89 } |
|
90 } |
|
91 |
|
92 // do not allow unreasonably large key sizes, probably user error |
|
93 try { |
|
94 RSAKeyFactory.checkKeyLengths(tmpKeySize, tmpPublicExponent, |
|
95 512, 64 * 1024); |
|
96 } catch (InvalidKeyException e) { |
|
97 throw new InvalidAlgorithmParameterException( |
|
98 "Invalid key sizes", e); |
|
99 } |
|
100 |
|
101 try { |
|
102 this.rsaId = RSAUtil.createAlgorithmId(type, tmpParams); |
|
103 } catch (ProviderException e) { |
|
104 throw new InvalidAlgorithmParameterException( |
|
105 "Invalid key parameters", e); |
|
106 } |
|
107 |
|
108 this.keySize = tmpKeySize; |
|
109 this.publicExponent = tmpPublicExponent; |
|
110 } |
|
111 |
|
112 // generate the keypair. See JCA doc |
|
113 public KeyPair generateKeyPair() { |
|
114 |
|
115 // accommodate odd key sizes in case anybody wants to use them |
|
116 BigInteger e = publicExponent; |
|
117 if (!e.equals(RSAKeyGenParameterSpec.F4)) { |
|
118 throw new AssertionError("Only support F4 now"); |
|
119 } |
|
120 BigInteger p, q, n; |
|
121 |
|
122 // Pre-calculated p and q for e == RSAKeyGenParameterSpec.F4 |
|
123 switch (keySize) { |
|
124 case 2048: |
|
125 p = new BigInteger("1600840041787354447543653385760927" |
|
126 + "2642568308955833364523274045522752644800599" |
|
127 + "8669541532595690224703734511692014533312515" |
|
128 + "1867029838883431415692353449578487671384896" |
|
129 + "6611685764860941767986520897595108597563035" |
|
130 + "4023785639802607792535812062420427283857665" |
|
131 + "9883578590844700707106157871508280052743363" |
|
132 + "65749456332400771"); |
|
133 q = new BigInteger("1303880717101677622201474394769850" |
|
134 + "7257196073324816341282215626935164930077468" |
|
135 + "5999131251387556761167658937349436378464220" |
|
136 + "4831804147777472146628148336776639855791417" |
|
137 + "3849903041999943901924899580268176393595653" |
|
138 + "7357080543898614581363167420619163047562600" |
|
139 + "6155574020606891195960345238780709194499010" |
|
140 + "43652862954645301"); |
|
141 break; |
|
142 case 4096: |
|
143 p = new BigInteger("2985635754414679487171962796211911" |
|
144 + "1563710734938215274736352092606404045130913" |
|
145 + "2477365484439939846705721840432140066578525" |
|
146 + "0762327458086280430118434094733412377416194" |
|
147 + "8736124795243564050755767519346747209606612" |
|
148 + "5835460937739428885308798309679495432910469" |
|
149 + "0294757621321446003970767164933974474924664" |
|
150 + "1513767092845098947552598109657871041666676" |
|
151 + "2945573325433283821164032766425479703026349" |
|
152 + "9433641551427112483593214628620450175257586" |
|
153 + "4350119143877183562692754400346175237007314" |
|
154 + "7121580349193179272551363894896336921717843" |
|
155 + "3734726842184251708799134654802475890197293" |
|
156 + "9094908310578403843742664173424031260840446" |
|
157 + "591633359364559754200663"); |
|
158 q = new BigInteger("2279248439141087793789384816271625" |
|
159 + "1304008816573950275844533962181244003563987" |
|
160 + "6638461665174020058827698592331066726709304" |
|
161 + "9231319346136709972639455506783245161859951" |
|
162 + "6191872757335765533547033659834427437142631" |
|
163 + "3801232751161907082392011429712327250253948" |
|
164 + "6012497852063361866175243227579880020724881" |
|
165 + "9393797645220239009219998518884396282407710" |
|
166 + "7199202450846395844337846503427790307364624" |
|
167 + "5124871273035872938616425951596065309519651" |
|
168 + "1519189356431513094684173807318945903212527" |
|
169 + "7712469749366620048658571121822171067675915" |
|
170 + "5479178304648399924549334007222294762969503" |
|
171 + "5341584429803583589276956979963609078497238" |
|
172 + "760757619468018224491053"); |
|
173 break; |
|
174 case 8192: |
|
175 p = new BigInteger("9821669838446774374944535804569858" |
|
176 + "0553278885576950130485823829973470553571905" |
|
177 + "3014418421996241500307589880457361653957913" |
|
178 + "9176499436767288125182942994089196450118944" |
|
179 + "8701794862752733776161684616570463744619126" |
|
180 + "4981622564763630694110472008409561205704867" |
|
181 + "0221819623405201369630462487520858670679048" |
|
182 + "5854008441429858453634949980424333056803703" |
|
183 + "1205609490778445762604050796894221725977551" |
|
184 + "1428887194691696420765173256600200430067305" |
|
185 + "4364524177041858044598166859757042904625691" |
|
186 + "4292728453597609683799189454690202563236931" |
|
187 + "8171122071288244573793276051041975005528757" |
|
188 + "0228306442708182141334279133965507583927772" |
|
189 + "9244311696220253059281524393613278272067808" |
|
190 + "7017494446447670799055720358621918361716353" |
|
191 + "5018317015764698318012095108914870478138809" |
|
192 + "8204738169777192718869484177321870413838036" |
|
193 + "8149216482968887382371881239714335470844573" |
|
194 + "1862934371951394070111726593305334971041399" |
|
195 + "5517260339034138718517336990212463882142363" |
|
196 + "9154412320743552301967162100734381046548816" |
|
197 + "3883737645359595416600487444018399886391071" |
|
198 + "3777667222706059170707223589163679915863781" |
|
199 + "4662302526078720977228426750718207481384357" |
|
200 + "7918717041190413457052439016978578217755022" |
|
201 + "7370720979516554707297685239584071755267452" |
|
202 + "6021894842754355160100506065457679069228273" |
|
203 + "95209345267367982516553449135291473361"); |
|
204 q = new BigInteger("7902448465953646210110784092684896" |
|
205 + "0265474424590294110174550047938700740921014" |
|
206 + "1981650823416127449143596912363210790070524" |
|
207 + "2903784112701128957948996730263815210531364" |
|
208 + "0489145287401377007608600217628773627723381" |
|
209 + "1194123533939872283952535576847014977682278" |
|
210 + "9332064706645169741712060131540562788886577" |
|
211 + "3762235020990267901959745687867018811088495" |
|
212 + "3716021011509120447248882358515954471433808" |
|
213 + "2782236662758287959413069553620728137831579" |
|
214 + "2321174813204514354999978428741310035945405" |
|
215 + "0226661395731921098764192439072425262100813" |
|
216 + "9732949866553839713092238096261034339815187" |
|
217 + "2832617055364163276140160068136296115910569" |
|
218 + "9466440903693740716929166334256441926903849" |
|
219 + "1082968246155177124035336609654226388424434" |
|
220 + "5775783323612758615407928446164631651292743" |
|
221 + "8428509642959278732826297890909454571009075" |
|
222 + "7836191622138731918099379467912681177757761" |
|
223 + "6141378131042432093843778753846726589215845" |
|
224 + "7402160146427434508515156204064224022904659" |
|
225 + "8645441448874409852211668374267341177082462" |
|
226 + "7341410218867175406105046487057429530801973" |
|
227 + "0931082058719258230993681115780999537424968" |
|
228 + "2385515792331573549935317407789344892257264" |
|
229 + "7464569110078675090194686816764429827739815" |
|
230 + "0566036514181547634372488184242167294602000" |
|
231 + "8232780963578241583529875079397308150506597" |
|
232 + "37190564909892937290776929541076192569"); |
|
233 break; |
|
234 default: |
|
235 throw new AssertionError("Unknown keySize " + keySize); |
|
236 } |
|
237 |
|
238 n = p.multiply(q); |
|
239 |
|
240 // phi = (p - 1) * (q - 1) must be relative prime to e |
|
241 // otherwise RSA just won't work ;-) |
|
242 BigInteger p1 = p.subtract(BigInteger.ONE); |
|
243 BigInteger q1 = q.subtract(BigInteger.ONE); |
|
244 BigInteger phi = p1.multiply(q1); |
|
245 // generate new p and q until they work. typically |
|
246 // the first try will succeed when using F4 |
|
247 if (e.gcd(phi).equals(BigInteger.ONE) == false) { |
|
248 throw new AssertionError("Should not happen"); |
|
249 } |
|
250 |
|
251 // private exponent d is the inverse of e mod phi |
|
252 BigInteger d = e.modInverse(phi); |
|
253 |
|
254 // 1st prime exponent pe = d mod (p - 1) |
|
255 BigInteger pe = d.mod(p1); |
|
256 // 2nd prime exponent qe = d mod (q - 1) |
|
257 BigInteger qe = d.mod(q1); |
|
258 |
|
259 // crt coefficient coeff is the inverse of q mod p |
|
260 BigInteger coeff = q.modInverse(p); |
|
261 |
|
262 try { |
|
263 PublicKey publicKey = new RSAPublicKeyImpl(rsaId, n, e); |
|
264 PrivateKey privateKey = new RSAPrivateCrtKeyImpl( |
|
265 rsaId, n, e, d, p, q, pe, qe, coeff); |
|
266 return new KeyPair(publicKey, privateKey); |
|
267 } catch (InvalidKeyException exc) { |
|
268 // invalid key exception only thrown for keys < 512 bit, |
|
269 // will not happen here |
|
270 throw new RuntimeException(exc); |
|
271 } |
|
272 } |
|
273 } |
|