test/jdk/sun/security/tools/keytool/pss/java.base/sun/security/rsa/RSAKeyPairGenerator.java
branchJDK-8200758-branch
changeset 57474 0af70fb03853
parent 57473 3ef9726d7eec
parent 55679 aa96c53c592b
child 57529 e3b156ad362f
equal deleted inserted replaced
57473:3ef9726d7eec 57474:0af70fb03853
     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 }