• 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 {
KeyPairTools()41     private KeyPairTools() {
42     }
43 
44     /**
45      * Field RSA.
46      */
47     public static final String RSA = "RSA";
48 
49     /**
50      * Field EC.
51      */
52     public static final String ECC = "EC";
53 
54     /**
55      * Field ECC.
56      */
57     public static final String ECC_INPUT = "ECC";
58 
59     /**
60      * Field RSA_2048.
61      */
62     public static final int RSA_2048 = 2048;
63 
64     /**
65      * Field RSA_3072.
66      */
67     public static final int RSA_3072 = 3072;
68 
69     /**
70      * Field RSA_4096.
71      */
72     public static final int RSA_4096 = 4096;
73 
74     /**
75      * Field NIST_P_256.
76      */
77     public static final int NIST_P_256 = 256;
78 
79     /**
80      * Field NIST_P_384.
81      */
82     public static final int NIST_P_384 = 384;
83 
84     /**
85      * Logger.
86      */
87     private static final Logger LOGGER = LogManager.getLogger(KeyPairTools.class);
88 
89 
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.equalsIgnoreCase(ECC_INPUT)) {
97             algorithm = ECC;
98         }
99         if (algorithm.equalsIgnoreCase(RSA)) {
100             ValidateUtils.throwIfNotMatches((keySize == RSA_2048 || keySize == RSA_3072 || keySize == RSA_4096),
101                     ERROR.NOT_SUPPORT_ERROR, "Algorithm 'RSA' not support size: " + keySize);
102         } else if (algorithm.equalsIgnoreCase(ECC)) {
103             ValidateUtils.throwIfNotMatches((keySize == NIST_P_256 || keySize == NIST_P_384),
104                     ERROR.NOT_SUPPORT_ERROR, "Algorithm 'ECC' not support size: " + keySize);
105         } else {
106             CustomException.throwException(ERROR.NOT_SUPPORT_ERROR, "Not support algorithm: " + algorithm);
107         }
108 
109         try {
110             KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
111             keyPairGenerator.initialize(keySize);
112             return keyPairGenerator.generateKeyPair();
113         } catch (NoSuchAlgorithmException e) {
114             LOGGER.debug(e.getMessage(), e);
115             CustomException.throwException(ERROR.NOT_SUPPORT_ERROR, e.getMessage());
116             return null;
117         }
118     }
119 
120     /**
121      * Convert key to String
122      *
123      * @param key input parameter and key can not be null.
124      * @return return key.getEncoded() in Base64 format.
125      */
key2String(Key key)126     public static String key2String(Key key) {
127         return Base64.toBase64String(key.getEncoded());
128     }
129 
130     /**
131      * Convert string back to key
132      *
133      * @param algorithm input parameter and algorithm can not be null.
134      * @param keyString input parameter and keyString can not be null.
135      * @return return PublicKey.
136      */
stringToPublicKey(String algorithm, String keyString)137     public static PublicKey stringToPublicKey(String algorithm, String keyString) {
138         X509EncodedKeySpec spec = new X509EncodedKeySpec(Base64.decode(keyString));
139         PublicKey result = null;
140         try {
141             result = KeyFactory.getInstance(algorithm).generatePublic(spec);
142         } catch (InvalidKeySpecException | NoSuchAlgorithmException exception) {
143             LOGGER.debug(exception.getMessage(), exception);
144             CustomException.throwException(ERROR.ACCESS_ERROR, exception.getMessage());
145         }
146         return result;
147     }
148 
149     /**
150      * Convert string back to key
151      *
152      * @param algorithm input parameter and algorithm can not be null.
153      * @param keyString input parameter and keyString can not be null.
154      * @return return PrivateKey.
155      */
stringToPrivateKey(String algorithm, String keyString)156     public static PrivateKey stringToPrivateKey(String algorithm, String keyString) {
157         PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(Base64.decode(keyString));
158         PrivateKey result = null;
159         try {
160             result = KeyFactory.getInstance(algorithm).generatePrivate(spec);
161         } catch (InvalidKeySpecException | NoSuchAlgorithmException exception) {
162             LOGGER.debug(exception.getMessage(), exception);
163             CustomException.throwException(ERROR.ACCESS_ERROR, exception.getMessage());
164         }
165         return result;
166     }
167 }
168