1.JAVA使用RSA加密算法解析数据
话不多说,直接开干
/**
*
* @param test
* @param request
* @return
*/
@RequestMapping(value = "/test", method = RequestMethod.POST)
public ResultVO<?> test(@RequestBody SecretBO secretBO, HttpServletRequest request) {
TestBO testBO = this.secretService.decryptpParameter(secretBO, TestBO.class);
String userId = request.getHeader("userId");
return this.testService.test(testBO, userId);
}
这是一个普通的接口,接下来我们分析一下解析里面的数据
/**
* 与前端商定结构
*
*/
@Data
public class SecretBO {
private String ciphertext;// 加密后的参数
private String key;// 公钥
private String time;//超时时间
}
TestBO就是封装好的BO类。下面来看具体处理:
import org.apache.commons.codec.binary.Base64;
import org.test.bean.bo.secret.SecretBO;
import org.test.contants.Codes;
import org.test.contants.Messages;
import org.test.exception.BusinessException;
import org.test.util.DESCoder;
import org.test.util.RSACoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSONObject;
@Service
public class SecretService {
private final static Logger logger = LoggerFactory.getLogger(SecretService.class);
// rsa:
// publicKey: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDn/QnUfkKkQpG++6YDUYo8qc0mrcRbRsmokp3EJZJrwIblldv6W2+yAIWkkel4GzsL+oklZReqZcG4F+ug3otc6IZa3fFMXuaDzoDzicdOABe2s8igLjMcfhujI9MqYvkVVSyFWdVOLNAnzQJgkisnHKZGPQZcxnQAHxTOUco+LwIDAQAB
// privateKey: MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAOf9CdR+QqRCkb77pgNRijypzSatxFtGyaiSncQlkmvAhuWV2/pbb7IAhaSR6XgbOwv6iSVlF6plwbgX66Dei1zohlrd8Uxe5oPOgPOJx04AF7azyKAuMxx+G6Mj0ypi+RVVLIVZ1U4s0CfNAmCSKyccpkY9BlzGdAAfFM5Ryj4vAgMBAAECgYBPBc63Z1rkARkMaUQflUL1bxHGvyJHxVEj7u12xyWdNrO8uNN58HOXur3LVTimBQCUD/9vkYQCMy9Nujg1UBlAIokG9zdhNkK/5x2y1yVOAL+SDQolnumZyTYncWTnNOZtgCdCnqBmuHpw6LfF5nHm7/iCeThdUY2MJ+u9y9wAIQJBAPuCuokJ/lZY0GI5hzxkeK9TlNYn6+rJpkAehkNz4Aaa6tjXaGcrKsLgHrYXupYKLNXABhELY70nJaahltUgF3UCQQDsIRp6/poRIbLCZ4JyoXp4Mjvd8lJ03mBUdzYEsn3aH9jafqOxLHB3FseYz/fKl3Gb5xgbhsFUCQm+3I9slu6TAkBEaSCX2dIGZo33ybIRKTryZYecYKt453SDCEp42nHbGhQ6+wx403MEIrX3zaiA2y+qzFpaFIECmD1Tf6xpOBtpAkEAwi/XHx8ShNQ5tjZ5yNuTZBWrtjL6LLJUdiIzgllntmJKbCWJaMMrGkTZkIo3NZymCZha8wg3JWzpXtTz/lGBkQJAb3kjcBZHRg53s6/CLi5eVEGVW0RjXWo47SpwYUuu1b5miG9oXlmZxyG9nS8ZFWcBKh0IZMlhcGCqvq2qNoC6qw==
@Value(value = "${rsa.privateKey}")
private String privateKey; //
@Value(value = "${time.interval}")
private String interval; // 600000 一个小时
@SuppressWarnings("unchecked")
public <T> T decryptpParameter(SecretBO secretBO, Class<T> clazz) {
try {
// 解密des秘钥
String secretKey = new String(RSACoder.decryptByPrivateKey(Base64.decodeBase64(secretBO.getKey()),
Base64.decodeBase64(privateKey)));
// 解密时间戳
Long time = Long
.parseLong(DESCoder.decrypt(Base64.decodeBase64(secretBO.getTime()), secretKey));
// 判断与当前时间的间隙
if (System.currentTimeMillis() - time > Long.parseLong(interval)) {
logger.error(Messages.TIME_INTERVAL_IS_TOO_LONG);
throw new BusinessException(Codes.CODE_500, Messages.DECRYPTP_PARAMETER_ERROR);
}
// 解密数据
String cleartext = DESCoder.decrypt(Base64.decodeBase64(secretBO.getCiphertext()), secretKey);
T value;
try {
value = JSONObject.parseObject(cleartext, clazz);
} catch (Exception e) {
value = (T) cleartext;
}
return value;
} catch (Exception e) {
logger.error(Messages.DECRYPTP_PARAMETER_ERROR, e);
throw new BusinessException(Codes.CODE_500, Messages.DECRYPTP_PARAMETER_ERROR); // 自定义的异常结构
}
}
}
提供一下处理方法
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
public class RSACoder {
// 非对称密钥算法
public static final String KEY_ALGORITHM = "RSA";
/**
* 密钥长度,DH算法的默认密钥长度是1024 密钥长度必须是64的倍数,在512到65536位之间
*/
private static final int KEY_SIZE = 1024;
// 公钥
private static final String PUBLIC_KEY = "RSAPublicKey";
// 私钥
private static final String PRIVATE_KEY = "RSAPrivateKey";
private static final int MAX_ENCRYPT_BLOCK = 117;
private static final int MAX_DECRYPT_BLOCK = 128;
/**
* 初始化密钥对
*
* @return Map 甲方密钥的Map
*/
public static Map<String, Object> initKey() throws Exception {
// 实例化密钥生成器
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
// 初始化密钥生成器
keyPairGenerator.initialize(KEY_SIZE);
// 生成密钥对
KeyPair keyPair = keyPairGenerator.generateKeyPair();
// 甲方公钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
// 甲方私钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
// 将密钥存储在map中
Map<String, Object> keyMap = new HashMap<String, Object>();
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
}
/**
* 私钥加密
*
* @param data 待加密数据
* @param key 密钥
* @return byte[] 加密数据
*/
public static byte[] encryptByPrivateKey(byte[] data, byte[] key) throws Exception {
// 取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 生成私钥
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
/**
* 公钥加密
*
* @param data 待加密数据
* @param key 密钥
* @return byte[] 加密数据
*/
public static byte[] encryptByPublicKey(byte[] data, byte[] key) throws Exception {
// 实例化密钥工厂
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 初始化公钥
// 密钥材料转换
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
// 产生公钥
PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);
// 数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
// 对数据分段解密
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] cache;
int inputLen = data.length;
int offSet = 0;
int i = 0;
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
}
/**
* 私钥解密
*
* @param data 待解密数据
* @param key 密钥
* @return byte[] 解密数据
*/
public static byte[] decryptByPrivateKey(byte[] data, byte[] key) throws Exception {
// 取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 生成私钥
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 数据解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
// 对数据分段解密
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] cache;
int inputLen = data.length;
int offSet = 0;
int i = 0;
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
}
/**
* 取得私钥
*
* @param keyMap 密钥map
* @return byte[] 私钥
*/
public static byte[] getPrivateKey(Map<String, Object> keyMap) {
Key key = (Key) keyMap.get(PRIVATE_KEY);
return key.getEncoded();
}
/**
* 取得公钥
*
* @param keyMap 密钥map
* @return byte[] 公钥
*/
public static byte[] getPublicKey(Map<String, Object> keyMap) throws Exception {
Key key = (Key) keyMap.get(PUBLIC_KEY);
return key.getEncoded();
}
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// 初始化密钥
// 生成密钥对
Map<String, Object> keyMap = RSACoder.initKey();
// 公钥
byte[] publicKey = RSACoder.getPublicKey(keyMap);
// 私钥
byte[] privateKey = RSACoder.getPrivateKey(keyMap);
System.out.println("公钥:/n" + Base64.encodeBase64String(publicKey));
System.out.println("私钥:/n" + Base64.encodeBase64String(privateKey));
}
这个工具类提供加密解密方法
效果:
image.png
总结:利用RAS加密方法可以让我们的程序安全性提高,但是也不是万能的,写程序一定要思路清晰,多校验。
网友评论