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