在网站登录时,会要求用户输入用户名、密码,在支付场景中,要求输入银行卡号、身份证号。这些敏感数据在传输过程中可能出现被截获破解、篡改的风险。即使网站使用了强大的HTTPS协议,恐怕也不可能百分百保证数据的传输安全。因此为了保证这些敏感数据的安全,在数据传输前需要进行加密处理。
实现流程
AES对称加密算法对业务请求参数进行加密后传输
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
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 AesUtil {
private static final String ALGORITHM="AES";
private static final int KEY_SIZE = 128;// 密钥位数
public static void main(String[] args) throws Exception {
String key = generateKey();
String s = "1234567891234";
String s1 = encode(key, s);
System.out.println("加密后:" + s1);
String s2 = decode(key, s1);
System.out.println("解密后:" + s2);
}
public static String generateKey() throws Exception{
KeyGenerator keygen = KeyGenerator.getInstance(ALGORITHM);
keygen.init(KEY_SIZE, new SecureRandom());
SecretKey secretKey = keygen.generateKey();
byte[] byteKey = secretKey.getEncoded();
String keyString = new String(Base64.encodeBase64(byteKey));
return keyString;
}
public static String encode(String keyStr, String contentStr) throws Exception {
byte[] keyByteArray = Base64.decodeBase64(keyStr);
Key key = new SecretKeySpec(keyByteArray, ALGORITHM);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] contentByteArray = contentStr.getBytes("UTF-8");
byte[] result = cipher.doFinal(contentByteArray);
return Base64.encodeBase64String(result);
}
public static String decode(String keyStr, String encodeContentStr) throws Exception {
byte[] keyByteArray = Base64.decodeBase64(keyStr);
Key key = new SecretKeySpec(keyByteArray, ALGORITHM);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] data = Base64.decodeBase64(encodeContentStr);
byte[] result = cipher.doFinal(data);
return new String(result);
}
}
RSA非对称加密算法对AES的密钥进行公钥加密后传输
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
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 RsaUtil {
private static final String ALGORITHM="RSA";// 非对称加密密钥算法
private static final int KEY_SIZE = 2048;// 密钥位数
private static final int DECRYPT_BLOCK = KEY_SIZE / 8;
private static final int ENCRYPT_BLOCK = KEY_SIZE / 8 - 11;
public static void main(String[] args) throws Exception {
Map<String, String> map = generateKeyPair();
String publicKey = map.get("publicKey");
String privateKey = map.get("privateKey");
String s = "12345678912345678989";
String s1 = encryptWithPublicKey(s, publicKey);
System.out.println("加密后:" + s1);
System.out.println("解密后:" + decryptWithPrivateKey(s1, privateKey));
String sa = "9876543219876543219821";
String sa1 = encryptWithPrivateKey(sa, privateKey);
System.out.println("加密后:" + sa1);
System.out.println("解密后:" + decryptWithPublicKey(sa1, publicKey));
}
public static Map<String, String> generateKeyPair() throws Exception{
Map<String, String> keyMap = new HashMap<String, String>();
KeyPairGenerator kpg = KeyPairGenerator.getInstance(ALGORITHM);
kpg.initialize(KEY_SIZE);
KeyPair keyPair = kpg.genKeyPair();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));
keyMap.put("publicKey", publicKeyString);
keyMap.put("privateKey", privateKeyString);
return keyMap;
}
public static String encryptWithPublicKey(String plain, String publicKey) throws Exception {
byte[] data = plain.getBytes("UTF-8");
byte[] key = Base64.decodeBase64(publicKey);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, RsaUtil.getPublicKey(key));
/**
* RSA算法规定:每次加密的字节数不能超过密钥的长度值除以8再减去11。
* 如果超过则需要分段加密
*/
for (int offset = 0; offset < data.length; offset += ENCRYPT_BLOCK) {
int inputLen = (data.length - offset);
if (inputLen > ENCRYPT_BLOCK) {
inputLen = ENCRYPT_BLOCK;
}
byte[] encryptedBlock = cipher.doFinal(data, offset, inputLen);
bos.write(encryptedBlock);
}
bos.close();
return Base64.encodeBase64String(bos.toByteArray());
}
public static String encryptWithPrivateKey(String plain, String privateKey) throws Exception {
byte[] data = plain.getBytes("UTF-8");
byte[] key = Base64.decodeBase64(privateKey);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, RsaUtil.getPrivateKey(key));
/**
* RSA算法规定:每次加密的字节数不能超过密钥的长度值除以8再减去11。
* 如果超过则需要分段加密
*/
for (int offset = 0; offset < data.length; offset += ENCRYPT_BLOCK) {
int inputLen = (data.length - offset);
if (inputLen > ENCRYPT_BLOCK) {
inputLen = ENCRYPT_BLOCK;
}
byte[] encryptedBlock = cipher.doFinal(data, offset, inputLen);
bos.write(encryptedBlock);
}
bos.close();
return Base64.encodeBase64String(bos.toByteArray());
}
public static String decryptWithPublicKey(String plain, String publicKey) throws Exception{
byte[] data = Base64.decodeBase64(plain);
byte[] key = Base64.decodeBase64(publicKey);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, RsaUtil.getPublicKey(key));
/**
* RSA算法规定:每次解密的字节数不能超过密钥的长度值除以8。
* 如果超过则需要分段解密
*/
for (int offset = 0; offset < data.length; offset += DECRYPT_BLOCK) {
int inputLen = (data.length - offset);
if (inputLen > DECRYPT_BLOCK) {
inputLen = DECRYPT_BLOCK;
}
byte[] decryptedBlock = cipher.doFinal(data, offset, inputLen);
bos.write(decryptedBlock);
}
bos.close();
return new String(bos.toByteArray());
}
public static String decryptWithPrivateKey(String plain, String privateKey) throws Exception{
byte[] data = Base64.decodeBase64(plain);
byte[] key = Base64.decodeBase64(privateKey);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, RsaUtil.getPrivateKey(key));
/**
* RSA算法规定:每次解密的字节数不能超过密钥的长度值除以8。
* 如果超过则需要分段解密
*/
for (int offset = 0; offset < data.length; offset += DECRYPT_BLOCK) {
int inputLen = (data.length - offset);
if (inputLen > DECRYPT_BLOCK) {
inputLen = DECRYPT_BLOCK;
}
byte[] decryptedBlock = cipher.doFinal(data, offset, inputLen);
bos.write(decryptedBlock);
}
bos.close();
return new String(bos.toByteArray());
}
private static PublicKey getPublicKey(byte[] key) throws Exception {
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
return keyFactory.generatePublic(keySpec);
}
private static PrivateKey getPrivateKey(byte[] key) throws Exception {
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
return keyFactory.generatePrivate(keySpec);
}
}