All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.linksfield.cube.partnersdk.utils.SignatureUtils Maven / Gradle / Ivy

package net.linksfield.cube.partnersdk.utils;

import lombok.Data;

import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * @ClassName SignatureUtils
 * @Description 签名工具
 * @Author James.hu
 * @Date 2023/2/13
 **/
public class SignatureUtils {
    private final static String SIGN_TYPE_RSA = "RSA";
    private final static String SIGN_ALGORITHMS = "SHA1WithRSA";
    private final static int KEYPAIR_LENGTH = 2048;

    /**
     * 获取私钥PKCS8格式(需base64)
     * @param algorithm
     * @param priKey
     * @return PrivateKey
     * @throws Exception
     */
    public static PrivateKey getPrivateKeyFromPKCS8(String algorithm, String priKey) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);

        byte[] encodedKey = Base64Utils.decodeFromString(priKey);

        return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey));
    }

    /**
     * 通过证书获取公钥(需BASE64,X509为通用证书标准)
     * @param algorithm
     * @param pubKey
     * @return PublicKey
     * @throws Exception
     */
    public static PublicKey getPublicKeyFromX509(String algorithm, String pubKey) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        byte[] encodeByte = Base64Utils.decodeFromString(pubKey);

        return keyFactory.generatePublic(new X509EncodedKeySpec(encodeByte));
    }

    /**
     * 使用私钥对字符进行签名
     * @param plain  内容体
     * @param prikey  私钥
     * @return String
     * @throws Exception
     */
    public static String sign(String plain, String prikey) throws Exception {
        if (isEmpty(plain, prikey)) {
            throw new IllegalArgumentException("Private key and encrypted data cannot be empty");
        }

        PrivateKey privatekey = getPrivateKeyFromPKCS8(SIGN_TYPE_RSA, prikey);
        Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
        signature.initSign(privatekey);
        signature.update(plain.getBytes(StandardCharsets.UTF_8));
        byte[] signed = signature.sign();

        return Base64Utils.encodeToString(signed);
    }

    /**
     * 将内容体、签名信息、及对方公钥进行验签
     * @param plain  内容体
     * @param sign   签名信息
     * @param pubkey  对方公钥
     * @return boolean
     * @throws Exception
     */
    public static boolean verify(String plain, String sign, String pubkey) throws Exception {
        if (isEmpty(plain, sign, pubkey)) {
            return false;
        }

        PublicKey publicKey = getPublicKeyFromX509(SIGN_TYPE_RSA, pubkey);
        Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
        signature.initVerify(publicKey);
        signature.update(plain.getBytes(StandardCharsets.UTF_8));
        return signature.verify(Base64Utils.decodeFromString(sign));
    }

    public static RsaKeyPair buildRsa() throws NoSuchAlgorithmException {
        // 获取指定算法的密钥对生成器
        KeyPairGenerator gen = KeyPairGenerator.getInstance(SIGN_TYPE_RSA);

        // 初始化密钥对生成器(指定密钥长度, 使用默认的安全随机数源)
        gen.initialize(KEYPAIR_LENGTH);

        // 随机生成一对密钥(包含公钥和私钥)
        KeyPair keyPair = gen.generateKeyPair();

        // 获取 公钥 和 私钥
        PublicKey pubKey = keyPair.getPublic();
        PrivateKey priKey = keyPair.getPrivate();

        // 获取 公钥和私钥 的 编码格式(通过该 编码格式 可以反过来 生成公钥和私钥对象)
        byte[] pubEncBytes = pubKey.getEncoded();
        byte[] priEncBytes = priKey.getEncoded();

        // 把 公钥和私钥 的 编码格式 转换为 Base64文本 方便保存
        String pubEncBase64 = Base64Utils.encodeToString(pubEncBytes);
        String priEncBase64 = Base64Utils.encodeToString(priEncBytes);

        RsaKeyPair pair = new RsaKeyPair();
        pair.setPublicKey(pubEncBase64);
        pair.setPrivateKey(priEncBase64);
        return pair;
    }


    @Data
    public static class RsaKeyPair {
        private String publicKey;
        private String privateKey;
    }


    public static boolean isEmpty(String... strings) {
        for (String string : strings) {
            if (isEmpty(string)) {
                return true;
            }
        }
        return false;
    }
    public static boolean isEmpty(String str) {
        return str == null || str.isEmpty() || !containsText(str);
    }
    private static boolean containsText(CharSequence str) {
        int strLen = str.length();

        for(int i = 0; i < strLen; ++i) {
            if (!Character.isWhitespace(str.charAt(i))) {
                return true;
            }
        }

        return false;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy