JAVA代码-公私钥加验签

Posted Krystal_*^*

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA代码-公私钥加验签相关的知识,希望对你有一定的参考价值。

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.util.IOUtils;
import org.apache.commons.codec.binary.Base64;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.URL;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Map;
import java.util.TreeMap;

/**
 * 主要包含签名、验签功能。
 * <p>
 * Created by wuxinw on 2017/5/3.
 */
public class SignUtil {
    public static final String PRIVATE_KEY_PATH = "zz.pfx";
    public static final String PUBLIC_KEY_PATH = "zz.cer";
    public static final String PRIVATE_KEY_PASSWD = "1231232";

    /**
     * 使用示例
     *
     * @param args
     * @throws FileNotFoundException
     * @throws KeyStoreException
     */
    public static void main(String[] args) throws FileNotFoundException, KeyStoreException {
        
        String body = "{\"id":\"1\", \"name":\"xiam\", \"year":\"2013\", \"old\":\"233\", \"hi\":\"hello\"}";
        Map<String, Object> parse = (JSONObject) JSONObject.parse(body, Feature.OrderedField);
        String signdata0 = (String) parse.remove("signdata");
        System.out.println("signdata0:" + signdata0);
        String s = params2PlainText(parse);
        System.out.println("加签原文:" + s);
        System.out.println("加签:" + sign(parse));
        boolean b = verifySign(s, sign(parse));
        System.out.println(b);
    }

    /**
     * 签名
     *
     * @return
     */
    public static String sign(Map<String, Object> params) {
        return sign(params2PlainText(params));
    }

    /**
     * 签名
     *
     * @param plainText
     * @return
     */
    public static String sign(String plainText) {
        try {
            Signature sig = Signature.getInstance("SHA1WithRSA");
            sig.initSign(getPrivateKey());
            sig.update(plainText.getBytes());
            byte[] b = sig.sign();
            return new String(Base64.encodeBase64(b));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static boolean verifySign(Map<String, Object> params, String signedText) {
        return verifySign(params2PlainText(params), signedText);
    }

    /**
     * 使用公钥验签
     *
     * @param plainText
     * @param signedText
     * @return
     */
    public static boolean verifySign(String plainText, String signedText) {
        try {
            signedText = signedText.replaceAll(" ", "+");
            Signature sig = Signature.getInstance("SHA1WithRSA");
            X509Certificate certificate = loadCertificate();
            sig.initVerify(certificate);
            sig.update(plainText.getBytes());
            byte[] b = Base64.decodeBase64(signedText.getBytes());
            return sig.verify(b);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 获取私钥
     *
     * @return
     */
    private static PrivateKey getPrivateKey() {
        String path = SignUtil.class.getClassLoader().getResource(PRIVATE_KEY_PATH).getPath();
        KeyStore ks = null;
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(path);
            ks = KeyStore.getInstance("PKCS12");
            ks.load(fis, PRIVATE_KEY_PASSWD.toCharArray());
            fis.close();
            String keyAlias = null;
            if (ks.aliases().hasMoreElements()) {
                keyAlias = ks.aliases().nextElement();
            }
            return (PrivateKey) ks.getKey(keyAlias, PRIVATE_KEY_PASSWD.toCharArray());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            IOUtils.close(fis);
        }
        return null;
    }

    /**
     * 参数转为签名原文
     *
     * @param params
     * @return
     */
    private static String params2PlainText(Map<String, Object> params) {
        TreeMap<String, Object> sortedParams = new TreeMap<>();
        sortedParams.putAll(params);
        StringBuilder plainText = new StringBuilder();
        for (String key : sortedParams.keySet()) {
            if (sortedParams.get(key) instanceof String || sortedParams.get(key) instanceof Number) {
                plainText.append("|").append(sortedParams.get(key));
            } else {
                plainText.append("|").append(JSONObject.toJSONString(sortedParams.get(key)));
            }
        }
        plainText.deleteCharAt(0);
        return plainText.toString();
    }


    /**
     * 获取公钥
     *
     * @return
     * @throws Exception
     */
    private static X509Certificate loadCertificate() throws Exception {
        CertificateFactory factory = CertificateFactory.getInstance("X.509");
        URL path = SignUtil.class.getClassLoader().getResource(PUBLIC_KEY_PATH);
        ClassLoader classLoader = Thread.currentThread()
                .getContextClassLoader();
        InputStream is = null;
        if (path != null)
            try {
                is = new FileInputStream(path.getFile());
            } catch (FileNotFoundException e) {
                is = classLoader.getResourceAsStream(PUBLIC_KEY_PATH);
            }
        else {
            is = new FileInputStream(PUBLIC_KEY_PATH);
        }
        X509Certificate certificate = (X509Certificate) factory.generateCertificate(is);
        is.close();
       
        return certificate;
    }


}

 

以上是关于JAVA代码-公私钥加验签的主要内容,如果未能解决你的问题,请参考以下文章

RSA加解密&RSA加验签

RSA公钥加密,私钥解密,私钥加签,公钥验签

一张图了解RSA加解密与加验签

一张图了解RSA加解密与加验签

Python rsa公私钥生成 rsa公钥加密(分段加密)私钥加签实战

RSA公私钥和签名、验签过程