在剛接觸RSA的時候,會混淆RSA加密解密和RSA加簽驗籤的概念。簡單來講加密解密是公鑰加密私鑰解密,持有公鑰(多人持有)能夠對數據加密,可是隻有持有私鑰(一人持有)才能夠解密並查看數據;加簽驗籤是私鑰加簽公鑰驗籤,持有私鑰(一人持有)能夠加簽,持有公鑰(多人持有)能夠驗籤。java
在金融行業在設計到數據交互傳輸的時候,須要考慮數據的安全性問題。下文經過介紹RSA的加密和加簽兩個特性,說明RSA加密技術在保障數據傳輸過程當中的安全性以及實現數據的防篡改和防否機制的應用場景及代碼實現。git
RSA加密解密主要應用於數據傳輸的安全性上。經過公鑰加密、私鑰解密的方式,能夠達到公鑰持有者可以加密數據,但只有私鑰持有者纔可以解密數據。經過加密傳輸數據可以避免被第三方截取者輕易的攔截數據,而經過RSA非對稱加密的特性也可以較好的保證第三方截取者在沒有私鑰的狀況下讀取數據內容。github
數據的的防否定機制是指數據的接收者能夠明確的知道數據的發送人。RSA的數字簽名技術是將摘要信息用發送者的私鑰(有且只有一人持有)加密,與原文一塊兒傳送給接收者。接收者只有用發送者的公鑰才能解密被加密的摘要信息,而後用HASH函數對收到的原文產生一個摘要信息,與解密的摘要信息對比。若是相同,則說明數據是有持有私鑰的發送者發出的(其餘人沒有私鑰,沒法生成一致的摘要信息)。所以在此基礎上能夠認爲有且只有一個私鑰的持有者才能夠加簽,達到數據的防止篡改防否定機制。算法
基於RSA的加密和驗籤功能,在對於數據傳輸安全性要求較高的交互應用中,能夠對原始數據進行加密加簽。具體流程以下圖↓apache
GitHub項目地址:https://github.com/suyin58/rsa-demo安全
package com.wjs.rsaDemo; import java.io.ByteArrayOutputStream; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.RSAPrivateKeySpec; import java.security.spec.RSAPublicKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map; import javax.crypto.Cipher; /** * RSA安全編碼組件 */ public abstract class RSAUtil{ public static final String KEY_ALGORITHM = "RSA"; public static final String SIGNATURE_ALGORITHM = "SHA1WithRSA"; private static final String PUBLIC_KEY = "RSAPublicKey"; private static final String PRIVATE_KEY = "RSAPrivateKey"; /** * 用私鑰對信息生成數字簽名 * * @param data * 加密數據 * @param privateKey * Base64編碼格式的私鑰 * * @return 通過Base64編碼的字符串 * @throws Exception */ public static String sign(byte[] data, String privateKey) throws Exception { // 解密由base64編碼的私鑰 byte[] keyBytes = HashUtil.decryptBASE64(privateKey); // 構造PKCS8EncodedKeySpec對象 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); // KEY_ALGORITHM 指定的加密算法 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 取私鑰匙對象 PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec); // 用私鑰對信息生成數字簽名 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initSign(priKey); signature.update(data); return HashUtil.encryptBASE64(signature.sign()); } /** * 校驗數字簽名 * * @param data * 加密數據 * @param publicKey * 公鑰 * @param sign * 數字簽名 * * @return 校驗成功返回true 失敗返回false * @throws Exception * */ public static boolean verify(byte[] data, String publicKey, String sign) throws Exception { // 解密由base64編碼的公鑰 byte[] keyBytes = HashUtil.decryptBASE64(publicKey); // 構造X509EncodedKeySpec對象 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); // KEY_ALGORITHM 指定的加密算法 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 取公鑰匙對象 PublicKey pubKey = keyFactory.generatePublic(keySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initVerify(pubKey); signature.update(data); // 驗證簽名是否正常 return signature.verify(HashUtil.decryptBASE64(sign)); } /** * 解密<br> * 用私鑰解密 * * @param data * @param key Base64編碼格式的私鑰 * @return * @throws Exception */ public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception { byte[] decryptedData = null; // 對密鑰解密 byte[] keyBytes = HashUtil.decryptBASE64(key); // 取得私鑰 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 對數據解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateKey); int maxDecryptBlockSize = getMaxDencryptBytesByPrivate(keyFactory, privateKey); ByteArrayOutputStream bout = new ByteArrayOutputStream(); try { int dataLength = data.length; for (int i = 0; i < dataLength; i += maxDecryptBlockSize) { int decryptLength = dataLength - i < maxDecryptBlockSize ? dataLength - i : maxDecryptBlockSize; byte[] doFinal = cipher.doFinal(data, i, decryptLength); bout.write(doFinal); } decryptedData = bout.toByteArray(); } finally { if (bout != null) { bout.close(); } } return decryptedData; } /** * 將Base64編碼的密文解密爲字符串 * @param base64Str * @param key * @return * @throws Exception * @author renteng * @date 2015年12月24日 下午12:35:34 */ public static String decryptByPrivateKeyToString(String base64Str, String key) throws Exception{ byte[] data = HashUtil.decryptBASE64(base64Str); byte[] oriData = decryptByPrivateKey(data, key); return new String(oriData); } /** * 獲取公鑰加密可加密的最大數據字節長度 * @param keyFactory * @param key * @return */ private static int getMaxEncryptBytesByPublicKey(KeyFactory keyFactory, Key key){ return getPublicKeyBitLength(keyFactory, key) / 8 - 11; } /** * 獲取公鑰解密每塊的字節長度 * @param keyFactory * @param key * @return */ private static int getMaxDencryptBytesByPrivate(KeyFactory keyFactory, Key key){ return getPrivateKeyBitLength(keyFactory, key) / 8; } /** * 獲取公鑰加密可加密的最大數據字節長度 * @param keyFactory * @param key * @return */ private static int getMaxEncryptBytesByPrivate(KeyFactory keyFactory, Key key){ return getPrivateKeyBitLength(keyFactory, key) / 8 - 11; } /** * 獲取公鑰解密每塊的字節長度 * @param keyFactory * @param key * @return */ private static int getMaxDencryptBytesByPublicKey(KeyFactory keyFactory, Key key){ return getPublicKeyBitLength(keyFactory, key) / 8; } /** * 獲取公鑰的字節長度 * @param keyFactory * @param key * @return */ private static int getPublicKeyBitLength(KeyFactory keyFactory, Key key){ try { RSAPublicKeySpec publicKeySpec = keyFactory.getKeySpec(key, RSAPublicKeySpec.class); return publicKeySpec.getModulus().bitLength(); } catch (Exception e) { } return 2048; } /** * 獲取私鑰的字節長度 * @param keyFactory * @param key * @return */ private static int getPrivateKeyBitLength(KeyFactory keyFactory, Key key){ try { RSAPrivateKeySpec publicKeySpec = keyFactory.getKeySpec(key, RSAPrivateKeySpec.class); return publicKeySpec.getModulus().bitLength(); } catch (Exception e) { } return 2048; } /** * 解密<br> * 用公鑰解密 * * @param data * @param key Base64編碼格式的公鑰 * @return * @throws Exception */ public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception { byte[] decryptedData = null; // 對密鑰解密 byte[] keyBytes = HashUtil.decryptBASE64(key); // 取得公鑰 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicKey = keyFactory.generatePublic(x509KeySpec); // 對數據解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicKey); int maxDecryptBlockSize = getMaxDencryptBytesByPublicKey(keyFactory, publicKey); ByteArrayOutputStream bout = new ByteArrayOutputStream(); try { int dataLength = data.length; for (int i = 0; i < dataLength; i += maxDecryptBlockSize) { int decryptLength = dataLength - i < maxDecryptBlockSize ? dataLength - i : maxDecryptBlockSize; byte[] doFinal = cipher.doFinal(data, i, decryptLength); bout.write(doFinal); } decryptedData = bout.toByteArray(); } finally { if (bout != null) { bout.close(); } } return decryptedData; } /** * 加密<br> * 用公鑰加密 * * @param data * @param key Base64編碼格式的公鑰 * @return * @throws Exception */ public static byte[] encryptByPublicKey(byte[] data, String key) throws Exception { byte[] encryptedData = null; // 對公鑰解密 byte[] keyBytes = HashUtil.decryptBASE64(key); // 取得公鑰 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicKey = keyFactory.generatePublic(x509KeySpec); // 對數據加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicKey); int maxEncryptBlockSize = getMaxEncryptBytesByPublicKey(keyFactory, publicKey); ByteArrayOutputStream bout = new ByteArrayOutputStream(); try { int dataLength = data.length; for (int i = 0; i < data.length; i += maxEncryptBlockSize) { int encryptLength = dataLength - i < maxEncryptBlockSize ? dataLength - i : maxEncryptBlockSize; byte[] doFinal = cipher.doFinal(data, i, encryptLength); bout.write(doFinal); } encryptedData = bout.toByteArray(); } finally { if (bout != null) { bout.close(); } } return encryptedData; } /** * 加密<br> * 用私鑰加密 * * @param data 密文二進制數據 * @param key BASE64編碼的私鑰字符串 * @return * @throws Exception */ public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception { byte[] encryptedData = null; // 對密鑰解密 byte[] keyBytes = HashUtil.decryptBASE64(key); // 取得私鑰 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 對數據加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateKey); int maxEncryptBlockSize = getMaxEncryptBytesByPrivate(keyFactory, privateKey); ByteArrayOutputStream bout = new ByteArrayOutputStream(); try { int dataLength = data.length; for (int i = 0; i < data.length; i += maxEncryptBlockSize) { int encryptLength = dataLength - i < maxEncryptBlockSize ? dataLength - i : maxEncryptBlockSize; byte[] doFinal = cipher.doFinal(data, i, encryptLength); bout.write(doFinal); } encryptedData = bout.toByteArray(); } finally { if (bout != null) { bout.close(); } } return encryptedData; } /** * 取得私鑰 * * @param keyMap * @return * @throws Exception */ public static String getPrivateKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PRIVATE_KEY); return HashUtil.encryptBASE64(key.getEncoded()); } /** * 取得公鑰 * * @param keyMap * @return * @throws Exception */ public static String getPublicKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PUBLIC_KEY); return HashUtil.encryptBASE64(key.getEncoded()); } /** * 初始化密鑰 * * @return * @throws Exception */ public static Map<String, Object> initKey() throws Exception { KeyPairGenerator keyPairGen = KeyPairGenerator .getInstance(KEY_ALGORITHM); keyPairGen.initialize(1024); KeyPair keyPair = keyPairGen.generateKeyPair(); // 公鑰 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 私鑰 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); Map<String, Object> keyMap = new HashMap<String, Object>(2); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } }
package com.wjs.rsaDemo; import java.security.MessageDigest; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; /** * 基礎加密組件 */ public abstract class HashUtil { public static final String KEY_SHA = "SHA"; public static final String KEY_SHA_256 = "SHA-256"; public static final String KEY_MD5 = "MD5"; /** * MAC算法可選如下多種算法 * * <pre> * HmacMD5 * HmacSHA1 * HmacSHA256 * HmacSHA384 * HmacSHA512 * </pre> */ public static final String KEY_MAC = "HmacMD5"; /** * BASE64解密 * * @param key * @return * @throws Exception */ public static byte[] decryptBASE64(String key) throws Exception { return Base64.decodeBase64(key); } /** * BASE64加密 * * @param key * @return * @throws Exception */ public static String encryptBASE64(byte[] key) throws Exception { return Base64.encodeBase64String(key); } /** * MD5加密 * * @param data * @return * @throws Exception */ public static byte[] encryptMD5(byte[] data) throws Exception { MessageDigest md5 = MessageDigest.getInstance(KEY_MD5); md5.update(data); return md5.digest(); } /** * SHA加密 * * @param data * @return * @throws Exception */ public static byte[] encryptSHA(byte[] data) throws Exception { MessageDigest sha = MessageDigest.getInstance(KEY_SHA); sha.update(data); return sha.digest(); } /** * SHA-256加密 * * @param data 待hash的二進制數據 * @return * @throws Exception */ public static byte[] encryptSHA256(byte[] data) throws Exception { MessageDigest sha = MessageDigest.getInstance(KEY_SHA_256); sha.update(data); return sha.digest(); } /** * 初始化HMAC密鑰 * * @return * @throws Exception */ public static String initMacKey() throws Exception { KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC); SecretKey secretKey = keyGenerator.generateKey(); return encryptBASE64(secretKey.getEncoded()); } /** * HMAC加密 * * @param data * @param key * @return * @throws Exception */ public static byte[] encryptHMAC(byte[] data, String key) throws Exception { SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC); Mac mac = Mac.getInstance(secretKey.getAlgorithm()); mac.init(secretKey); return mac.doFinal(data); } }
package com.wjs.rsaDemo; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.HashMap; import java.util.Map; public class RsaDemo { /** * 加簽用公鑰 */ public static String signPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3GFaW5S8GI7ejxhnVjhC6is3k5ZXY+eHK7hV42W7aSPuQ1dg72XZ2D/cLIdv4wNf8H3vf0e2O0YNwuwst6rD/BWey0yBUnToTm6xsJg5dCMYNQCocgtDrBTgHYSkZY/eno0MMn1KdRN0ILvAvz4BmENOkfuD3TEHgzXZS+prDZOKIHfW0HUYNEGk3LQC6VKQawKY+QO7k188wokV85FzmYFvjkkOE0UHuFL/p2zGnwVv+ZHq34TzZQaQNnO3/INQqxi+HiPfpD2oTJDY1+cAqukCD46hM+4qPx4t6A1fe+Tr8GE4DeGW3+MIqcuCs79cGj1Xtca8AoGCqK/Nx2Y0JwIDAQAB"; /** * 加簽用私鑰 */ public static String signPrivateKey = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDcYVpblLwYjt6PGGdWOELqKzeTlldj54cruFXjZbtpI+5DV2DvZdnYP9wsh2/jA1/wfe9/R7Y7Rg3C7Cy3qsP8FZ7LTIFSdOhObrGwmDl0Ixg1AKhyC0OsFOAdhKRlj96ejQwyfUp1E3Qgu8C/PgGYQ06R+4PdMQeDNdlL6msNk4ogd9bQdRg0QaTctALpUpBrApj5A7uTXzzCiRXzkXOZgW+OSQ4TRQe4Uv+nbMafBW/5kerfhPNlBpA2c7f8g1CrGL4eI9+kPahMkNjX5wCq6QIPjqEz7io/Hi3oDV975OvwYTgN4Zbf4wipy4Kzv1waPVe1xrwCgYKor83HZjQnAgMBAAECggEAJWZYIUaijUBhwMMRdm5h3L+s1N0kw42dQOwtl0PChFtWqhMAHmCYkbx0rxHlCQ+fjn6w0FbpNDH1T+koxZqzW+qHYlT/dXDlo7nhaejLh0wVZZlQ/NmwiFmalyfVhm7eBuZE9aSRqEC+6ncyhMIPHzn88YVPoZAaiEfxMpL7y/e3UAXfnzMFXqVi2ihMbtu6w1FUMgnWjy8WqqwgoTFVdR6GjWUROAtfTUwZe6Fw+KVm2+KKgMWPPE2SPxXp3q0T6AwI6Eg1RbIjUYUsl/9DkUdXJBt9G6eaNbY7WkeRrN8HKMCA1zOIv2sJWEnHkg2N6FgTHkSWIBXjiJ5vsphXUQKBgQDvcd0+J0PT1qAphgg3xTjQBim7MOsFG2VvQH0r72Fj4qy2BOsRyuotBJBQlgyq/csyduHew/068qWCCQb534dTvVtOXXQ1rSvyIM/UjFM0/5BExtKluz1zm2tQt0KDEOyZ1OnbGryuV8Ap8ftAfy1XkiVeqo1E9T6ej1kRzopABQKBgQDrngzRKsQPKDaCHb7Wn4QxYq5u8bYXn/EymynOjJcGxeJ/KotFCcemWFlWjIsi/k0sCJ3yWATARqCd7eSYcW/AmNpe2b/g4w699WvlSWq+E5hCA/GVwQpwRJSYN/PhDqdkBRngJ/AD8lf6CEGxG3SaMYCfXCkdFYwYYgdRGfUXOwKBgA3ERiwkpcmwNVUt15sdQ77yG8Qfc+O/R321/3xfLwJHLhbpAXrsZ7pe4M1BU0khfmVQYHwmWJDjEpD/Y99J8sXlxTIkPWI4qqYpLMnTp5UMfIb3x3Sv50CWVv01DCXs+y19CFUInICJmwrOVtvGdBzs0ik3NRgZ4ZfMNhrH/TrhAoGAB55BndW7Jx5OvOBHVlssBAjDyRSJpbPnMZKwxFvpWi+1xhTTEfVh/i/nG5RJv2Tni9/vc3GDHdBqyxBxDrjEOz71+JEj0hqlVGEGDxDTobeyeZf1DLmEI+MjxtQwT3uQz/wWPRgte4MvcwcnUJmpqH6nQP/S2Hzk3bj1sZqcQRcCgYBG4JCI7b1qJnvOPyP4Eqt6GcZ3OpbwkwKkiYQ2lwgn+wHT/7l3HfpTpBKZFMSknrbD11MzE2Q6niP6luG+HZPBsLyEQduipqaFe/GLmTGjljnj2wG3981sQluyrNlNPbDrTQKQERkcy6v8L6NHnIsYrUT/uHC6UJTqVYWjk1WVeQ=="; /** * 加密用私鑰 */ private static String encryptPrivateKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCd4FMhHvZGRBAMuRqn0ZmvvNFBkYyGsf9NOaS+CMAgHB4ib+ciDE3lCfYZHhi0vV2iMMBIanwaNev4c0uu4WyeFLQkMAUbgW/iIo+pR8xocjo9RPsTxN0IOL4KpSeTLM2MQZKnyffBugoIt15mZzzij6lcXy2CI/2wcNKg4Nw6v1iZ8Et+wEgqlPVeASaTAFSjmJNQn4aIy8Fpzll8ADP9neUQCMOWG87lDbU9RCs0YqAFfo61MyYj+KbIvhWwyycZJIrKFwKsEn4tViB5UFegRP4DgSjEzq/glvnwgVNBDiYFOKZ8lqkS+bfhHBA+w+X+fJ2CTalKm3+NZTHYeX5DAgMBAAECggEAf9p1N/NtGkZwgP0+2v1havKMvH70wPhReubdxZAsl1RuCxF4qxgv1PaWOI0pEOXyeDDm5z5lNozIhrJIbl3cqsC1ikDhQf827nlywnKE1Wj8RTYh50acgdYCAXjybbvw0k8gR4XGgTr6eUiWyHN+2TPiwg3KOwSOpF8aFHNFpsSbwrOg7xlzNov6M28B/godUpGgPv0PuN7M6DMOi18QiwWSPa1ycnBt7tWZkyEl/vMdAV0be2RfY93Lvzgp8a/mI+A/c8hcBJj5vJDwJR3CnqKR5RceOPrA4eT2zXJOcR43DfWPo7Q+7Buii1ERoSF3Um4t5JpSr/2j2xHdJGmRMQKBgQDfODepUuiKMW5IPVdkdF62oDmF/CLkizbDsAPXeG6tWPZUYX7cHkoEuPY0LxACIcM3ZnZyCUBtIDMk7bLEIw3wuXqh+1hVQrS5VCosbVq6LxcT5MMQouMxRtHSScdIcsGUYZSIVjlXuQdDXzrKhg3LSTLdWdYAb4pIygHb0UbsxwKBgQC1D5Izs3UGFXpySMdeDo8eF4TkmQqGlYI1rEkZxHNcSH9BGTJH3EmuAb5/8UxSDWX7GPpLJeexSVHrfADYl4CmYpDITpihhaB+t68b9yHY7EwO/gF2QcTvvwIIfWJmjPyCJTwT6wRtmv5WQnt7tt0ObZq0tovJVdn8cbpyVLAOpQKBgQCaTWs0siorNSZN65FY0JSUW8fH1dZs88sElMzjCs4/KCsHg2nFUW7LOux+gDXps1sWFc803y5ZARQ5p9KWgMDnMeASzwNt1LHHFuYcVe+MmnayesVY37B7ZMAwRG3sp98m6hlZ8XisKixaJx8l1mr8pnnxx2MGZBRMYs/MGyuTCwKBgALxOtX+P5OWu8OprRu5Ltg1V6KDXilruo72usVhbOJ+BxtetnN2f/gE7TyVBkF7GEIpWL/p4Mb/wwYJoNXkOGH7zhCDPnW5fy8v+veAX5tv05iWxh1O2k1vFDBhIT07Y0sWIdDNC+hgEWwDbpBHG3aFj3MKWGEwNPemPXpoJ+hFAoGBAJioGALh7yp4bpHTdwrGtSWm8TdXBx8nC8rFNI9SUtSopafN2eHLwZ6PnVvN6kgCIlQ7HbxQruuGKiKd9UDTbEbFIaidUAoyzZm7/cYc0YJRVXnQNLiiz758VHtx1YEdscMXj10X4NSK8sRMjeWQhT1v5PaNafG65oSkuyFrIlPk"; /** * 加密用公鑰 */ public static String encryptPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAneBTIR72RkQQDLkap9GZr7zRQZGMhrH/TTmkvgjAIBweIm/nIgxN5Qn2GR4YtL1dojDASGp8GjXr+HNLruFsnhS0JDAFG4Fv4iKPqUfMaHI6PUT7E8TdCDi+CqUnkyzNjEGSp8n3wboKCLdeZmc84o+pXF8tgiP9sHDSoODcOr9YmfBLfsBIKpT1XgEmkwBUo5iTUJ+GiMvBac5ZfAAz/Z3lEAjDlhvO5Q21PUQrNGKgBX6OtTMmI/imyL4VsMsnGSSKyhcCrBJ+LVYgeVBXoET+A4EoxM6v4Jb58IFTQQ4mBTimfJapEvm34RwQPsPl/nydgk2pSpt/jWUx2Hl+QwIDAQAB"; public static void main(String[] args) { // 組裝數據 encode("加簽數據"); // 解籤 System.out.println("解籤後數據---->" + decode()); } // 參數容器 static Map<String, String> paramMap = new HashMap<String, String>(); private static String charset = "utf-8"; public static void encode(String bizParam) { try { // 使用網金社公鑰對業務參數進行加密 String bizParamEncrypt = HashUtil .encryptBASE64(RSAUtil.encryptByPublicKey(bizParam.getBytes(charset), encryptPublicKey)); paramMap.put("bizParams", URLEncoder.encode(bizParamEncrypt, charset)); // 計算並組裝簽名 String sign = RSAUtil.sign(bizParam.getBytes(charset), signPrivateKey); paramMap.put("sign", URLEncoder.encode(sign, charset)); } catch (Exception e) { e.printStackTrace(); } } public static String decode() { // 解密參數 String bizParams = paramMap.get("bizParams"); try { bizParams = URLDecoder.decode(bizParams, charset); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } String bizParamsJson = null; try { bizParamsJson = new String( RSAUtil.decryptByPrivateKey(HashUtil.decryptBASE64(bizParams), encryptPrivateKey)); } catch (Exception e) { e.printStackTrace(); } // 驗籤 checkSign(bizParamsJson, signPublicKey, paramMap.get("sign")); return bizParamsJson; } private static void checkSign(String data, String publicKey, String sign) { boolean verify = false; try { sign = URLDecoder.decode(sign, charset); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } try { verify = RSAUtil.verify(data.getBytes(charset), publicKey, sign); } catch (Exception e) { e.getMessage(); } if (!verify) { System.err.println("驗籤失敗"); } else { System.out.println("驗籤成功"); } } }