Java公鑰私鑰對及數據簽名

import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.apache.commons.codec.binary.Hex;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description KeyPairSignUtil
 * @Author dsf
 * @Date 2020/12/19 12:13
 * @Version V1.0
 **/
public class KeyPairSignUtil {

    /**
     *  生成RSA公、私鑰對
     * */
    public static Map<String, String> generateRSAKeyPair() throws Exception{
        KeyPairGenerator keyPairGenerator = null;
        try {
            keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        } catch (NoSuchAlgorithmException e){
            throw e ;
        }
        keyPairGenerator.initialize(512);
        //祕鑰對
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        //公鑰
        PublicKey publicKey = keyPair.getPublic();
        //私鑰
        PrivateKey privateKey = keyPair.getPrivate();

        String publicKeyStr = java.util.Base64.getEncoder().encodeToString(publicKey.getEncoded());
        String privateKeyStr = java.util.Base64.getEncoder().encodeToString(privateKey.getEncoded());

        Map<String, String> map = new HashMap();
        map.put("PRIVATE_KEY", privateKeyStr);
        map.put("PUBLIC_KEY", publicKeyStr);
        return map;
    }

    /**
     * 進行簽名
     * @param  base64RsaPrivateKey 被進行BASE64編碼的RAS算法生成的私鑰
     * @param  data 要被簽名的數據
     * */
    public static String generateRSASignature(String base64RsaPrivateKey,String data) throws Exception {
        byte[] bytes = java.util.Base64.getDecoder().decode(base64RsaPrivateKey) ;
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(bytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        Signature signature = Signature.getInstance("MD5withRSA");
        signature.initSign(privateKey);
        signature.update(data.getBytes("UTF-8"));
        //生成簽名
        byte[] result = signature.sign();
        return  Hex.encodeHexString(result) ;
    }

    /**
     * 對簽名進行驗證
     * @param  base64RsaPublicKey 被進行BASE64編碼的RAS算法生成的公鑰
     * @param  hexSign   十六進制編碼後的簽名
     * @param  signData 被簽名的數據
     * */
    public static boolean verify(String base64RsaPublicKey,String hexSign,String signData) throws Exception {
        byte[] bytes = java.util.Base64.getDecoder().decode(base64RsaPublicKey) ;
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(bytes);
        KeyFactory keyFactory  = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
        Signature signature = Signature.getInstance("MD5withRSA");
        signature.initVerify(publicKey);
        signature.update(signData.getBytes("UTF-8"));
        return signature.verify(Hex.decodeHex(hexSign)) ;
    }

    /**
     * 建立通過BASE64編碼後的祕鑰
     * */
    public static String generateSecretKey(){
        Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
        return java.util.Base64.getEncoder().encodeToString(key.getEncoded());
    }

    /**
     * 根據BASE64編碼後的祕鑰建立SecretKey對象
     * */
    public static SecretKey newSecretKey (String base64SecretKey) {
        byte[] encodedKey = java.util.Base64.getDecoder().decode(base64SecretKey);
        return new SecretKeySpec(encodedKey, SignatureAlgorithm.HS256.getJcaName());
    }

    public static void main(String[] args) throws Exception {
        Map<String, String>  keyPairMap = generateRSAKeyPair() ;
        String base64RsaPrivateKey = keyPairMap.get("PRIVATE_KEY") ;
        String base64RsaPublicKey = keyPairMap.get("PUBLIC_KEY") ;
        System.out.println(base64RsaPrivateKey);
        System.out.println(base64RsaPublicKey);

        String data = "這是一個神奇的2020年" ;
        //簽名結果
        String hexSign = generateRSASignature(base64RsaPrivateKey,data) ;
        System.out.println(hexSign);
        //驗證簽名結果
        boolean result = verify(base64RsaPublicKey,hexSign,data) ;
        System.out.println(result);

        String base64SecretKey = generateSecretKey() ;
        System.out.println(base64SecretKey);

        SecretKey secretKey = newSecretKey(base64SecretKey) ;
        System.out.println(secretKey.toString());
    }
}
相關文章
相關標籤/搜索