天天看點

RSA密鑰對生成工具代碼RSA密鑰對生成工具

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")));
    }
           

密鑰檔案:

RSA密鑰對生成工具代碼RSA密鑰對生成工具

密鑰内容:

RSA密鑰對生成工具代碼RSA密鑰對生成工具

Github代碼倉

已上傳github代碼倉,代碼倉位址:key-pair-tool,代碼倉代碼支援多種非對稱加密算法密鑰的生成,歡迎指正補充功能。