目录
一、对称加密和非对称加密的区别
1、算法
- 对称加密常见有:DES、AES、3DES
- 非对称加密常见有:RSA、ECC
2、密钥
- 对称加密:加密和解密都用同一个密钥
- 非对称加密:需要两个密钥,公钥加密,私钥解密
3、安全风险
- 对称加密因为是一个密钥,密钥需要提供到对手方,所以有泄露的风险,
- 而非对称加密公钥公开,私钥自己保存,所以泄露风险几乎没有
4、效率
- 对称加密的效率要远高于非对称加密
5、使用场景
- 如果是非安全网络或者其他场景 (例如Android开发的app,对密码等信息加密)密钥有暴露的风险,推荐使用非对称加密
- 如果是安全网络环境,使用对称加密,效率高
- 主要是根据两者密钥的区别,来判断区分选择使用
二、对称加密DES的实现工具类
- 注意:工作模式ECB不能使用向量、CBC等模式都需要向量
- 只是简单的demo,根据自己需要调整入参,例如密钥和向量都可改为配置更灵活
@Slf4j
public class DesSecurityUtil {
/**
* 加密密码
*/
private final static String KEY = "12345678@!#$%";
/**
* 密钥算法
*/
private static final String ALGORITHM = "DES";
/**
* 加密/解密算法-工作模式-填充模式
* ECB模式不能使用向量
* CBC等模式都需要向量
*/
private static final String CIPHER_ALGORITHM = "DES/CBC/PKCS5Padding";
/**
* 向量 偏移变量,固定占8位字节
*/
private static final String IV_PARAMETER = "qwerty78";
public static void main(String[] args) {
String data = "my name is xxx";
String encrypt = encrypt(data);
String decrypt = decrypt(encrypt);
log.info("resultData = {}",data);
log.info("encrypt = {}",encrypt);
log.info("decrypt = {}",decrypt);
}
/**
* DES加密字符串
* @param data 待加密字符串
* @return 加密后内容
*/
public static String encrypt(String data) {
if (StringUtils.isBlank(data)) {
log.error("待解密数据为空");
return null;
}
try {
Key secretKey = generateKey();
IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(StandardCharsets.UTF_8));
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, secretKey,iv);
return Base64Utils.encodeToString(cipher.doFinal(data.getBytes(StandardCharsets.UTF_8)));
} catch (Exception e) {
log.error("加密失败",e);
return null;
}
}
/**
* DES解密字符串
* @param data 待解密字符串
* @return 解密后内容
*/
public static String decrypt(String data) {
if (StringUtils.isBlank(data)) {
log.error("带解密数据为空");
return null;
}
try {
Key secretKey = generateKey();
IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(StandardCharsets.UTF_8));
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, secretKey,iv);
return new String(cipher.doFinal(Base64Utils.decodeFromString(data)), StandardCharsets.UTF_8);
} catch (Exception e) {
log.error("加密失败",e);
return null;
}
}
/**
* 生成key
*
* @return
* @throws Exception
*/
private static Key generateKey() throws Exception {
DESKeySpec dks = new DESKeySpec(KEY.getBytes(StandardCharsets.UTF_8));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
return keyFactory.generateSecret(dks);
}
}
三:非对称加密RSA的工具类
- 公钥和密钥网上工具生产一组即可
public class RsaSecurityUtil {
private static final String ALGO = "RSA";
private static final String CHARSET = "UTF-8";
private static final String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr6i7mUB7fmSZRxVpyoqA302s+njRuGfEEyKq9Bzx+SPmVAxZZsfm5CLt6fhlnHat05CDfyQuvyM4fLSkH3OzFhE+462Vo79zY++ftUzLQIGmhF2cJA6wkbNKJTQF5FkhBUTAdEdKvppODjB7kLnc/juXZbDxLhR4o4pjH7+olXdKL317qyfYZjTa+HE2HEZCh6zkEbdY6+hisKlHRfmZa7RdgytSaIiXyGGlE9jMQLAxOC/N3yK0GrwSZC2d5yLpo2y2Y+REO+qjuHJkFvGq+cna/K+hCpqhOH2TaAzVVKlA8sCrwiI+Sz8R8MsBWJjKwZ+BEu4V1AgPPS22WSc/4QIDAQAB";
private static final String PRIVATE_KEY = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCvqLuZQHt+ZJlHFWnKioDfTaz6eNG4Z8QTIqr0HPH5I+ZUDFlmx+bkIu3p+GWcdq3TkIN/JC6/Izh8tKQfc7MWET7jrZWjv3Nj75+1TMtAgaaEXZwkDrCRs0olNAXkWSEFRMB0R0q+mk4OMHuQudz+O5dlsPEuFHijimMfv6iVd0ovfXurJ9hmNNr4cTYcRkKHrOQRt1jr6GKwqUdF+ZlrtF2DK1JoiJfIYaUT2MxAsDE4L83fIrQavBJkLZ3nIumjbLZj5EQ76qO4cmQW8ar5ydr8r6EKmqE4fZNoDNVUqUDywKvCIj5LPxHwywFYmMrBn4ES7hXUCA89LbZZJz/hAgMBAAECggEALcpSfPSuPJiEzF7soPvR9GQPP4vXP7btCf/ziIczHLsbA7XkaEKcEcR5OJCkDFFzpr75SF9qQDEyPG/qiLhkatA8EKXjaDg0IE0K2PwXz8z8V2z/kvaxWIngPip9jrUdQn5VnPoopd8bkd9ZlrScwzlNkhi6BkUX3anphRE1JSDwWIxqId4HkaFbv476SEZIOkZf/Q2QKOmUfyp/GSawPMEM3xdnWQk91tkWuZCXaYdXKZ3asUPMBiSX9u8iZe0/Q5R3tXfIzFxgr6ZPDoMAEDiO61/8H3GuyN7KsrtiMbyihY6aqhLvWCp5QG9Qx0ZziHYrIMNqpiGJRxdlVxe78QKBgQDtN8U1VcAKsAG+tVgfCa000xBc7qNpOYbaxaQoLItssEhT1u02gBMX3XxUygyddtzBzIEXPbij1u7DlW9pW5hF+rgYtdY/H4LgZzz16NmwQwsZobjSIQB/UIP66CvZRKnBwHqMaIyiz23cBOhdBz4FeMJJsVgybVr7v0p19F5C3wKBgQC9kTZoC47cwvPp9Z2l291vwfBZSstU9PKAp3vTs4HQX9DUvpRx2qoF8Kp9Yfaa4wTf6Xq91h+Zjmq8gNXr0rHSVtUsbQdF19E9eQX6XYjdtwkXuoYCpgYMpkIRjcDnPzALLmvCyzR8FsrlUdVRNA5OYbafJt3xpLXWC3QtiReVPwKBgBrdXAokQfFz6V6truMk92aqGIpNxFfgWfNguqyKDugqNqa4CnlHm+HyBWic0Tzr/yg7fsshBE4Zw0SHIezuoJocQMkbnr3bVbkQOAkpa63YieNHO2Ugs6u3dJrvvDeI3SjCIZ7RIEw37ZsjOyV98nowKOCrou9jDxC/ozEkkaBFAoGAZuy0DJPR8n0LMAlCmi4hMa+sDt80PSFtlXraGZyKLBgJ66i6MoMV83mzJ7aLzZbbK7O6B959c8NGoqiU/aB9GgY5YhCkdUBzhBv0qfYk/LSHhFGqtz9rY2zVzHAZv7SoIjoHGlF4YrOBYDcpShiod9hH7muM78mNTPUVFDAuFMMCgYBUsq4qkOjW68i/TSAudRdC5nFIQlMxTFvO+x/EADCvSMUggJh5utXVOXf3Z7lcI3A+RRMAVj4kVBVbsIRi941AhyVB+nYm6QV7G+XTVqQcTkHqv3pT99pvRcXMKF12/OQBsboFMDLzjKgiDAVw3nuuEVu6vGkhyo8ny3rqajLIIg==";
/**
* RSA公钥加密
*
* @param data 加密字符串
* @param publicKey 公钥
* @return 密文
* @throws Exception 加密过程中的异常信息
*/
public static String encrypt(String data, String publicKey) throws Exception {
// base64 编码的公钥
byte[] decoded = Base64.getDecoder().decode(publicKey);
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance(ALGO).generatePublic(new X509EncodedKeySpec(decoded));
// RSA加密
Cipher cipher = Cipher.getInstance(ALGO);
// 公钥加密
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
return Base64.getEncoder().encodeToString(cipher.doFinal(data.getBytes(CHARSET)));
}
/**
* RSA私钥解密
*
* @param data 加密字符串
* @param privateKey 私钥
* @return 铭文
* @throws Exception 解密过程中的异常信息
*/
public static String decrypt(String data, String privateKey) throws Exception {
byte[] inputByte = Base64.getDecoder().decode(data.getBytes(CHARSET));
// base64 编码的私钥
byte[] decoded = Base64.getDecoder().decode(privateKey);
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance(ALGO).generatePrivate(new PKCS8EncodedKeySpec(decoded));
// RSA 解密
Cipher cipher = Cipher.getInstance(ALGO);
// 私钥解密
cipher.init(Cipher.DECRYPT_MODE, priKey);
return new String(cipher.doFinal(inputByte));
}
public static void main(String[] args) {
String originData = "Rsa security test123!";
System.out.println("originData = " + originData);
try {
String encryData = encrypt(originData, PUBLIC_KEY);
System.out.println("encryData = " + encryData);
String decryData = decrypt(encryData, PRIVATE_KEY);
System.out.println("decryData = " + decryData);
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 额外提供一个公钥私钥生成的方法,有可能会用到
private static void generateKeyPair() throws NoSuchAlgorithmException {
// KeyPairGenerator 类用于生成公钥和私钥对,基于RSA算法生成对象
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
// 初始化密钥对生成器,密钥大小为 96-1024 位
keyPairGen.initialize(2048, new SecureRandom());
// 生成一个密钥对,保存在 keyPair 中
KeyPair keyPair = keyPairGen.generateKeyPair();
// 得到私钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
// 得到公钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
String publicKeyString = new String(Base64.getEncoder().encode(publicKey.getEncoded()));
// 得到私钥字符串
String privateKeyString = new String(Base64.getEncoder().encode((privateKey.getEncoded())));
System.out.println("publicKey="+publicKeyString);
System.out.println("privateKeyString="+privateKeyString);
}