RSA安全性應用場景說明
在剛接觸RSA的時候,會混淆RSA加密解密和RSA加簽驗簽的概念。簡單來說加密解密是公鑰加密私鑰解密,持有公鑰(多人持有)可以對資料加密,但是隻有持有私鑰(一人持有)才可以解密并檢視資料;加簽驗簽是私鑰加簽公鑰驗簽,持有私鑰(一人持有)可以加簽,持有公鑰(多人持有)可以驗簽。
在金融行業在設計到資料互動傳輸的時候,需要考慮資料的安全性問題。下文通過介紹RSA的加密和加簽兩個特性,說明RSA加密技術在保障資料傳輸過程中的安全性以及實作資料的防篡改和防否機制的應用場景及代碼實作。
RSA在資料安全上的應用
加密:資料傳輸的安全性
RSA加密解密主要應用于資料傳輸的安全性上。通過公鑰加密、私鑰解密的方式,可以達到公鑰持有者能夠加密資料,但隻有私鑰持有者才能夠解密資料。通過加密傳輸資料能夠避免被第三方截取者輕易的攔截資料,而通過RSA非對稱加密的特性也能夠較好的保證第三方截取者在沒有私鑰的情況下讀取資料内容。
加簽:資料的防篡改、防否認機制
資料的的防否認機制是指資料的接收者可以明确的知道資料的發送人。RSA的數字簽名技術是将摘要資訊用發送者的私鑰(有且隻有一人持有)加密,與原文一起傳送給接收者。接收者隻有用發送者的公鑰才能解密被加密的摘要資訊,然後用HASH函數對收到的原文産生一個摘要資訊,與解密的摘要資訊對比。如果相同,則說明資料是有持有私鑰的發送者發出的(其他人沒有私鑰,無法生成一緻的摘要資訊)。是以在此基礎上可以認為有且隻有一個私鑰的持有者才可以加簽,達到資料的防止篡改防否認機制。
RSA資料安全傳輸的實作
基于RSA的加密和驗簽功能,在對于資料傳輸安全性要求較高的互動應用中,可以對原始資料進行加密加簽。具體流程如下圖↓
示例工程
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;
}
}
RSAutil
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);
}
}
HashUtil
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("驗簽成功");
}
}
}