• 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.key;
17 
18 import com.ohos.hapsigntool.api.ServiceApi;
19 import com.ohos.hapsigntool.error.CustomException;
20 import com.ohos.hapsigntool.error.ERROR;
21 import com.ohos.hapsigntool.utils.ValidateUtils;
22 import org.apache.logging.log4j.LogManager;
23 import org.apache.logging.log4j.Logger;
24 import org.bouncycastle.util.encoders.Base64;
25 
26 import java.security.Key;
27 import java.security.KeyFactory;
28 import java.security.KeyPair;
29 import java.security.KeyPairGenerator;
30 import java.security.PublicKey;
31 import java.security.PrivateKey;
32 import java.security.NoSuchAlgorithmException;
33 import java.security.spec.InvalidKeySpecException;
34 import java.security.spec.PKCS8EncodedKeySpec;
35 import java.security.spec.X509EncodedKeySpec;
36 
37 /**
38  * Key pair relation Class, to create new key pairs.
39  *
40  * @since 2021/12/28
41  */
42 public final class KeyPairTools {
KeyPairTools()43     private KeyPairTools() {
44     }
45 
46     /**
47      * Field RSA.
48      */
49     public static final String RSA = "RSA";
50 
51     /**
52      * Field EC.
53      */
54     public static final String ECC = "EC";
55 
56     /**
57      * Field ECC.
58      */
59     public static final String ECC_INPUT = "ECC";
60 
61     /**
62      * Field RSA_2048.
63      */
64     public static final int RSA_2048 = 2048;
65 
66     /**
67      * Field RSA_3072.
68      */
69     public static final int RSA_3072 = 3072;
70 
71     /**
72      * Field RSA_4096.
73      */
74     public static final int RSA_4096 = 4096;
75 
76     /**
77      * Field NIST_P_256.
78      */
79     public static final int NIST_P_256 = 256;
80 
81     /**
82      * Field NIST_P_384.
83      */
84     public static final int NIST_P_384 = 384;
85 
86     /**
87      * Logger.
88      */
89     private static final Logger LOGGER = LogManager.getLogger(ServiceApi.class);
90 
91 
92     /**
93      * @param algorithm RSA/ECC
94      * @param keySize   RSA_2048/3072/4096 NIST_P_256/384
95      * @return Generated keypair
96      */
generateKeyPair(String algorithm, int keySize)97     public static KeyPair generateKeyPair(String algorithm, int keySize) {
98         if (algorithm.equalsIgnoreCase(ECC_INPUT)) {
99             algorithm = ECC;
100         }
101         if (algorithm.equalsIgnoreCase(RSA)) {
102             ValidateUtils.throwIfNotMatches((keySize == RSA_2048 || keySize == RSA_3072 || keySize == RSA_4096),
103                     ERROR.NOT_SUPPORT_ERROR, "Algorithm 'RSA' not support size: " + keySize);
104         } else if (algorithm.equalsIgnoreCase(ECC)) {
105             ValidateUtils.throwIfNotMatches((keySize == NIST_P_256 || keySize == NIST_P_384),
106                     ERROR.NOT_SUPPORT_ERROR, "Algorithm 'ECC' not support size: " + keySize);
107         } else {
108             CustomException.throwException(ERROR.NOT_SUPPORT_ERROR, "Not support algorithm: " + algorithm);
109         }
110 
111         try {
112             KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
113             keyPairGenerator.initialize(keySize);
114             return keyPairGenerator.generateKeyPair();
115         } catch (NoSuchAlgorithmException e) {
116             LOGGER.debug(e.getMessage(), e);
117             CustomException.throwException(ERROR.NOT_SUPPORT_ERROR, e.getMessage());
118             return null;
119         }
120     }
121 
122     /**
123      * Convert key to String
124      *
125      * @param key input parameter and key can not be null.
126      * @return return key.getEncoded() in Base64 format.
127      */
key2String(Key key)128     public static String key2String(Key key) {
129         return Base64.toBase64String(key.getEncoded());
130     }
131 
132     /**
133      * Convert string back to key
134      *
135      * @param algorithm input parameter and algorithm can not be null.
136      * @param keyString input parameter and keyString can not be null.
137      * @return return PublicKey.
138      */
stringToPublicKey(String algorithm, String keyString)139     public static PublicKey stringToPublicKey(String algorithm, String keyString) {
140         X509EncodedKeySpec spec = new X509EncodedKeySpec(Base64.decode(keyString));
141         PublicKey result = null;
142         try {
143             result = KeyFactory.getInstance(algorithm).generatePublic(spec);
144         } catch (InvalidKeySpecException | NoSuchAlgorithmException exception) {
145             LOGGER.debug(exception.getMessage(), exception);
146             CustomException.throwException(ERROR.ACCESS_ERROR, exception.getMessage());
147         }
148         return result;
149     }
150 
151     /**
152      * Convert string back to key
153      *
154      * @param algorithm input parameter and algorithm can not be null.
155      * @param keyString input parameter and keyString can not be null.
156      * @return return PrivateKey.
157      */
stringToPrivateKey(String algorithm, String keyString)158     public static PrivateKey stringToPrivateKey(String algorithm, String keyString) {
159         PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(Base64.decode(keyString));
160         PrivateKey result = null;
161         try {
162             result = KeyFactory.getInstance(algorithm).generatePrivate(spec);
163         } catch (InvalidKeySpecException | NoSuchAlgorithmException exception) {
164             LOGGER.debug(exception.getMessage(), exception);
165             CustomException.throwException(ERROR.ACCESS_ERROR, exception.getMessage());
166         }
167         return result;
168     }
169 }
170