hiKirin 2019-04-06
加密算法按是否可逆分为单向加密和双向加密。
单向加密是不可逆的,也就是说只能进行加密,不能进行解密。通常用来传输或者存储敏感数据,如用户名、密码等。单向加密原则上不可破解,网络上所谓的破解实际上都属于碰撞,就是把常见的明文进行加密成密文后将明文和密文存储起来,然后逆向查询得到明文。常见的单向加密算法有MD5和SHA等。
双向加密又称为可逆加密,分为对称加密和非对称加密。
对称加密指加密和解密采用相同的密钥进行加解密的算法。对称加密的优点在于加解密的速度快和破解难度和密钥长度正相关。常见的对称加密算法:DES、3DES、IDEA、RC4、RC5、RC6、AES等。
非对称加密指加密和解密使用不同的密钥进行加解密的算法,因此也称为公私钥加密。假设两个用户要加密交换数据,双方交换公钥,使用时一方用对方的公钥加密,另一方即可用自己的私钥解密。非对称加密可以用来进行加解密,也可以用来进行加签和验签。常见的非对称加密算法:RSA、 DSA、 ECC等。
另外提一点:加密和解密都是配对密钥进行的,可以公钥加密私钥解密,也可以私钥加密公钥解密。但是为了安全,通常都是以对方的公钥加密,自持私钥解密。
对称加密密钥管理比较难,不适合互联网,一般用于内部系统,安全性一般,加密速度快。
非对称加密密钥管理简单,安全性高,加密速度慢,适合小数据量的数据加密和数据签名。
以下为RSA加密算法工具类,仅供参考:
package com.huatech.common.util;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
/**
* 工具类
*/
public class RSAUtil {
/**
* 读取秘钥数据
* @param keyFilePath
* @return
*/
public static byte[] readKeyDatas(String keyFilePath){
BufferedReader bufferedReader=null;
try{
bufferedReader = new BufferedReader(new FileReader(keyFilePath));
String str=null;
StringBuilder stringBuilder=new StringBuilder();
while ((str=bufferedReader.readLine())!=null){
if(str.contains("---")){
continue;
}
stringBuilder.append(str);
}
return stringBuilder.toString().getBytes();
}catch (IOException e) {
e.printStackTrace();
}finally {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
/**
* 读取公钥
* @param publicKeyPath
* @return
*/
public static PublicKey getPublicKey(String publicKeyPath){
//1.读取公钥文件,获取公钥数据
byte[] bytesPublicBase64 = readKeyDatas(publicKeyPath);
//2.对读取回来的数据进行Base64解码
byte[] bytesPublic = Base64.getDecoder().decode(bytesPublicBase64);
//3.把解码后的数据,重新封装成一个PublicKey对象
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytesPublic);
KeyFactory keyFactory=null;
try {
keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return null;
}
/**
* 读取私钥
* @param privateKeyPath
* @return
*/
public static PrivateKey getPrivateKey(String privateKeyPath){
//1.读取私钥文件,获取私钥数据
byte[] bytesPrivateBase64 = readKeyDatas(privateKeyPath);
//2.对读取回来的数据进行Base64解码
byte[] bytesPrivate = Base64.getDecoder().decode(bytesPrivateBase64);
//3.把解码后的数据,重新封装成一个PrivateKey对象
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytesPrivate);
KeyFactory keyFactory=null;
try {
keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return null;
}
/**
* 加密数据
* @param publicKey
* @param originData
* @return
*/
public static String encodeData(PublicKey publicKey,String originData){
try {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE,publicKey);
byte[] bytesEncrypt = cipher.doFinal(originData.getBytes());
//Base64编码
byte[] bytesEncryptBase64 = Base64.getEncoder().encode(bytesEncrypt);
return new String(bytesEncryptBase64);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
return null;
}
/**
* 解密数据
* @param privateKey
* @param encodeData
* @return
*/
public static String decodeData(PrivateKey privateKey,String encodeData){
try {
//Base64解码
byte[] bytesEncrypt = Base64.getDecoder().decode(encodeData);
//加密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] bytesDecrypt = cipher.doFinal(bytesEncrypt);
return new String(bytesDecrypt);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
return null;
}
/**
* 签名
* @param privateKey
* @param data
* @return
*/
public static byte[] signData(PrivateKey privateKey, String data){
byte[] signed = null;
Signature signature;
try {
signature = Signature.getInstance("Sha1WithRSA");
signature.initSign(privateKey);
signature.update(data.getBytes("UTF-8"));
signed = signature.sign();
} catch (NoSuchAlgorithmException e) {
} catch (InvalidKeyException e) {
} catch (SignatureException | UnsupportedEncodingException e) {
}
return signed;
}
/**
* 验签
* @param publicKey
* @param data
* @param signed
* @return
*/
public static boolean verifySign(PublicKey publicKey, String data, byte[] signed){
boolean verify = false;
Signature signature2;
try {
signature2 = Signature.getInstance("Sha1WithRSA");
signature2.initVerify(publicKey);
signature2.update(data.getBytes("UTF-8"));
verify = signature2.verify(signed);
} catch (NoSuchAlgorithmException e) {
} catch (InvalidKeyException e) {
} catch (SignatureException | UnsupportedEncodingException e) {
}
return verify;
}
}