RSA加密解密及RSA加签验签
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("验签成功");
} } }
RSA加密解密及RSA加签验签的更多相关文章
- RSA加密解密及RSA签名和验证及证书
RSA加密解密及RSA签名和验证及证书 公钥是给别人的 发送密文使用公钥加密 验证签名使用公钥验证 私钥是自己保留的 接受密文使用私钥解密 发送签名使用私钥签名 上述过程逆转是不行的,比如使用私钥加密 ...
- RSA加密解密及RSA签名和验证
原文:RSA加密解密及RSA签名和验证 1.RSA加密解密: (1)获取密钥,这里是产生密钥,实际应用中可以从各种存储介质上读取密钥 (2)加密 (3)解密2.RSA签名和验证 (1)获取密钥,这里是 ...
- 银联手机支付(.Net Csharp),3DES加密解密,RSA加密解密,RSA私钥加密公钥解密,.Net RSA 3DES C#
前段时间做的银联支付,折腾了好久,拼凑的一些代码,有需要的朋友可以参考,本人.Net新手,不保证准确性! 这个银联手机支付没有SDK提供,技术支持也没有.Net的,真心不好搞! RSA加解密,这里有个 ...
- C#-java RSA加密解密
using Org.BouncyCastle.Math; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Securi ...
- RSA加密解密(转)
RSA加密解密 对于RSA产生的公钥.私钥,我们可以有两种方式可以对信息进行加密解密.私钥加密-公钥解密 和 公钥加密-私钥解密RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest) ...
- RSA加密解密和读取公钥、私钥
/// <summary> /// RSA加密解密及RSA签名和验证 /// </summary> public class RSADE { ...
- RSA加密解密与加签验签
RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的.1987年7月首次在美国公布 ...
- 微信小程序(17)-- RSA加密 解密 加签 验签
RSA加密 解密 加签 验签 /** * 注:区分RSA私钥的类型,有pkcs1和pkcs8.pkcs8格式的私钥主要用于Java中 pkcs1格式: -----BEGIN RSA PRIVATE K ...
- RSA 加密 解密 公钥 私钥 签名 加签 验签
http://blog.csdn.net/21aspnet/article/details/7249401# http://www.ruanyifeng.com/blog/2013/06/rsa_al ...
随机推荐
- Builder模式详解及其在Android开发中的应用
一.引言 在Android开发中,采用Builder模式的代码随处可见,比如说Android系统对话框AlertDialog的使用或者是Android中的通知栏(Notification)的使用,又比 ...
- 几种Android数据序列化方案
一.引言 数据的序列化在Android开发中占据着重要的地位,无论是在进程间通信.本地数据存储又或者是网络数据传输都离不开序列化的支持.而针对不同场景选择合适的序列化方案对于应用的性能有着极大的影响. ...
- 【JavaScript学习】-JS内置对象1-对象概述
对象(object): JavaScript 中的所有事物都是对象,如:字符串.数值.数组.函数等,每个对象带有属性和 方法.JavaScript 提供多个内建对象,比如 String.Date.Ar ...
- Hadoop 笔记1 (原理和HDFS分布式搭建)
1. hadoop 是什么 以及解决的问题 (自行百度) 2.基本概念的讲解 1. NodeName master 节点(NN) 主节点 保存了metaData(元数据信息) 包括文件的owener ...
- ip地址0.0.0.0与127.0.0.1的区别(转载)
原文链接:http://blog.csdn.net/ttx_laughing/article/details/58586907 最近在项目开发中发现一个奇怪的问题,当服务器与客户端在同一台机器上时,用 ...
- sql嵌套批量更新
嵌套批量更新 UPDATE CheLiang SET lineName = t.linename FROM TeamJiHua t ,CheLiang tc WHERE t.id = tc.teami ...
- H5个性三级联动日期插件(一)
1. 先看效果:如图 2.如果跟你的需求一样的话,那就抓紧down(当)起来吧! 首先你的页面可能需要很多的开发需求文件: jquery,mobiscroll 等js框架插件等 自己参照官方的demo ...
- Chapter 5. MPEG-4 Visual
本章着重介绍有关MPEG-4 Visual标准的细节. Tool 编码工具集合的子集(比如支持交织等). Object 视频元素(比如一个矩形视频帧,或者一个任意形状的区域,静止的图像). Profi ...
- 4.jsp的内置对象
1.jsp有九大内置对象 out request response session application page pagecontext exception config 2.用户发请求 requ ...
- Java 9 揭秘(7. 创建自定义运行时映像)
Tips 做一个终身学习的人. 在第一章节中,主要介绍以下内容: 什么是自定义运行时映像和JIMAGE格式 如何使用jlink工具创建自定义的运行时映像 如何指定命令名称来运行存储在自定义映像中的应用 ...