• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 package com.ohos.hapsigntool.utils;
17 
18 import com.ohos.hapsigntool.error.CustomException;
19 import com.ohos.hapsigntool.error.ERROR;
20 import org.apache.logging.log4j.LogManager;
21 import org.apache.logging.log4j.Logger;
22 import org.bouncycastle.util.encoders.Base64;
23 
24 import java.security.Key;
25 import java.security.KeyFactory;
26 import java.security.KeyPair;
27 import java.security.KeyPairGenerator;
28 import java.security.PublicKey;
29 import java.security.PrivateKey;
30 import java.security.NoSuchAlgorithmException;
31 import java.security.spec.InvalidKeySpecException;
32 import java.security.spec.PKCS8EncodedKeySpec;
33 import java.security.spec.X509EncodedKeySpec;
34 
35 /**
36  * Key pair relation Class, to create new key pairs.
37  *
38  * @since 2021/12/28
39  */
40 public final class KeyPairTools {
41     /**
42      * Field RSA.
43      */
44     public static final String RSA = "RSA";
45 
46     /**
47      * Field EC.
48      */
49     public static final String ECC = "EC";
50 
51     /**
52      * Field ECC.
53      */
54     public static final String ECC_INPUT = "ECC";
55 
56     /**
57      * Field RSA_2048.
58      */
59     public static final int RSA_2048 = 2048;
60 
61     /**
62      * Field RSA_3072.
63      */
64     public static final int RSA_3072 = 3072;
65 
66     /**
67      * Field RSA_4096.
68      */
69     public static final int RSA_4096 = 4096;
70 
71     /**
72      * Field NIST_P_256.
73      */
74     public static final int NIST_P_256 = 256;
75 
76     /**
77      * Field NIST_P_384.
78      */
79     public static final int NIST_P_384 = 384;
80 
81     /**
82      * Logger.
83      */
84     private static final Logger LOGGER = LogManager.getLogger(KeyPairTools.class);
85 
KeyPairTools()86     private KeyPairTools() {}
87 
88     /**
89      * generateKeyPair
90      *
91      * @param algorithm RSA/ECC
92      * @param keySize   RSA_2048/3072/4096 NIST_P_256/384
93      * @return Generated keypair
94      */
generateKeyPair(String algorithm, int keySize)95     public static KeyPair generateKeyPair(String algorithm, int keySize) {
96         if (algorithm == null) {
97             CustomException.throwException(ERROR.NOT_SUPPORT_ERROR, "Not support algorithm: null");
98         }
99         String alg = algorithm;
100         if (ECC_INPUT.equalsIgnoreCase(alg)) {
101             alg = ECC;
102         }
103         if (RSA.equalsIgnoreCase(alg)) {
104             ValidateUtils.throwIfNotMatches((keySize == RSA_2048 || keySize == RSA_3072 || keySize == RSA_4096),
105                     ERROR.NOT_SUPPORT_ERROR, "Algorithm 'RSA' not support size: " + keySize);
106         } else if (ECC.equalsIgnoreCase(alg)) {
107             ValidateUtils.throwIfNotMatches((keySize == NIST_P_256 || keySize == NIST_P_384),
108                     ERROR.NOT_SUPPORT_ERROR, "Algorithm 'ECC' not support size: " + keySize);
109         } else {
110             CustomException.throwException(ERROR.NOT_SUPPORT_ERROR, "Not support algorithm: " + alg);
111         }
112 
113         try {
114             KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(alg);
115             keyPairGenerator.initialize(keySize);
116             return keyPairGenerator.generateKeyPair();
117         } catch (NoSuchAlgorithmException e) {
118             LOGGER.debug(e.getMessage(), e);
119             CustomException.throwException(ERROR.NOT_SUPPORT_ERROR, e.getMessage());
120             return null;
121         }
122     }
123 
124     /**
125      * Convert key to String
126      *
127      * @param key input parameter and key can not be null.
128      * @return return key.getEncoded() in Base64 format.
129      */
key2String(Key key)130     public static String key2String(Key key) {
131         return Base64.toBase64String(key.getEncoded());
132     }
133 
134     /**
135      * Convert string back to key
136      *
137      * @param algorithm input parameter and algorithm can not be null.
138      * @param keyString input parameter and keyString can not be null.
139      * @return return PublicKey.
140      */
stringToPublicKey(String algorithm, String keyString)141     public static PublicKey stringToPublicKey(String algorithm, String keyString) {
142         X509EncodedKeySpec spec = new X509EncodedKeySpec(Base64.decode(keyString));
143         PublicKey result = null;
144         try {
145             result = KeyFactory.getInstance(algorithm).generatePublic(spec);
146         } catch (InvalidKeySpecException | NoSuchAlgorithmException exception) {
147             LOGGER.debug(exception.getMessage(), exception);
148             CustomException.throwException(ERROR.ACCESS_ERROR, exception.getMessage());
149         }
150         return result;
151     }
152 
153     /**
154      * Convert string back to key
155      *
156      * @param algorithm input parameter and algorithm can not be null.
157      * @param keyString input parameter and keyString can not be null.
158      * @return return PrivateKey.
159      */
stringToPrivateKey(String algorithm, String keyString)160     public static PrivateKey stringToPrivateKey(String algorithm, String keyString) {
161         PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(Base64.decode(keyString));
162         PrivateKey result = null;
163         try {
164             result = KeyFactory.getInstance(algorithm).generatePrivate(spec);
165         } catch (InvalidKeySpecException | NoSuchAlgorithmException exception) {
166             LOGGER.debug(exception.getMessage(), exception);
167             CustomException.throwException(ERROR.ACCESS_ERROR, exception.getMessage());
168         }
169         return result;
170     }
171 }
172