RSA密鑰對生成工具
- RSA密鑰對生成工具
-
- RSA密鑰生成
- RSA密鑰寫入檔案
- RSA密鑰生成測試
- Github代碼倉
RSA密鑰對生成工具
最近研究License方案,用到了Java生成RSA公私鑰的方法,分享一下。
RSA密鑰生成
利用Java自帶的安全包
java.security.*
生成RSA(3072)密鑰對,并将二進制資料存儲到Map傳回:
import java.security.*;
import java.util.HashMap;
import java.util.Map;
public class KeyTool {
public static final String PUBLIC_KEY = "publicKey";
public static final String PRIVATE_KEY = "privateKey";
public Map<String, byte[]> generateKeys() throws NoSuchAlgorithmException {
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
generator.initialize(3072);
KeyPair keyPair = generator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
Map<String, byte[]> keyMap = new HashMap<>();
keyMap.put(PUBLIC_KEY, publicKey.getEncoded());
keyMap.put(PRIVATE_KEY, privateKey.getEncoded());
return keyMap;
}
}
RSA密鑰寫入檔案
将二進制key資料存儲到檔案,method為枚舉,可以存儲為十六進制字元串或Base64字元串:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.*;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
public class KeyTool {
public static final String PUBLIC_KEY = "publicKey";
public static final String PRIVATE_KEY = "privateKey";
/**
* 生成密鑰并存儲到檔案
*
* @param publicKeyPath 公鑰存儲路徑
* @param privateKeyPath 私鑰存儲路徑
* @param method 存儲方法(十六進制字元串/Base64字元串)
* @throws NoSuchAlgorithmException
* @throws IOException
*/
public void generateKeyFiles(String publicKeyPath, String privateKeyPath, KeySaveMethod method) throws NoSuchAlgorithmException, IOException {
Map<String, byte[]> keyMap = generateKeys();
String publicKey = getKeyString(keyMap.get(PUBLIC_KEY), method);
String privateKey = getKeyString(keyMap.get(PRIVATE_KEY), method);
Files.writeString(Paths.get(publicKeyPath), publicKey);
Files.writeString(Paths.get(privateKeyPath), privateKey);
}
public Map<String, byte[]> generateKeys() throws NoSuchAlgorithmException {
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
generator.initialize(3072);
KeyPair keyPair = generator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
Map<String, byte[]> keyMap = new HashMap<>();
keyMap.put(PUBLIC_KEY, publicKey.getEncoded());
keyMap.put(PRIVATE_KEY, privateKey.getEncoded());
return keyMap;
}
private String getKeyString(byte[] encoding, KeySaveMethod method) {
return switch (method) {
case HEX -> HexUtils.toHexString(encoding);
case BASE64 -> Base64.getEncoder().encodeToString(encoding);
};
}
}
存儲方法枚舉:
public enum KeySaveMethod {
/**
* Convert binary data of key into hexadecimal string.
*/
HEX,
/**
* Convert the binary data of key into Base64 string.
*/
BASE64
}
16進制字元串和二進制互轉工具:
public class HexUtils {
private static final int[] DEC = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15};
private static final char[] HEX = "0123456789abcdef".toCharArray();
private HexUtils() {
}
public static int getDec(int index) {
try {
return DEC[index - 48];
} catch (ArrayIndexOutOfBoundsException var2) {
return -1;
}
}
public static String toHexString(byte[] bytes) {
if (null == bytes) {
return null;
} else {
StringBuilder sb = new StringBuilder(bytes.length << 1);
int var3 = bytes.length;
for (int var4 = 0; var4 < var3; ++var4) {
byte aByte = bytes[var4];
sb.append(HEX[(aByte & 240) >> 4]).append(HEX[aByte & 15]);
}
return sb.toString();
}
}
public static byte[] fromHexString(String input) {
if (input == null) {
return null;
} else if ((input.length() & 1) == 1) {
throw new IllegalArgumentException("The input must consist of an even number of hex digits");
} else {
char[] inputChars = input.toCharArray();
byte[] result = new byte[input.length() >> 1];
for (int i = 0; i < result.length; ++i) {
int upperNibble = getDec(inputChars[2 * i]);
int lowerNibble = getDec(inputChars[2 * i + 1]);
if (upperNibble < 0 || lowerNibble < 0) {
throw new IllegalArgumentException("The input must consist only of hex digits");
}
result[i] = (byte) ((upperNibble << 4) + lowerNibble);
}
return result;
}
}
}
RSA密鑰生成測試
public static void main(String[] args) throws NoSuchAlgorithmException, IOException {
KeyTool keyTool = new KeyTool();
keyTool.generateKeyFiles("D://public.key", "D://private.key", KeySaveMethod.BASE64);
System.out.println("Public Key: " + Files.readString(Paths.get("D://public.key")));
System.out.println("Private Key: " + Files.readString(Paths.get("D://private.key")));
}
密鑰檔案:
密鑰内容:
Github代碼倉
已上傳github代碼倉,代碼倉位址:key-pair-tool,代碼倉代碼支援多種非對稱加密算法密鑰的生成,歡迎指正補充功能。