1、对称加密算法,如:AES、DES、3DES
对称秘钥加密,就是采用这种加密方法的双方使用方式用同样的密钥进行加密和解密。密钥是控制加密及解密过程的指令
2、非对称加密算法,如:RSA、DSA、ECC
非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥 (privatekey)。公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。
3、散列算法 ,如:MD5、SHA1、HMAC,非可逆加密,就是不可解密的加密方法
用于确保信息传输完整一致
4、BASE64 严格地说,属于编码格式,而非加密算法
BASE64
public class Base64Utils {
/**
* BASE64字符串解码为二进制数据
*/
public static byte[] decode(String base64) throws Exception {
return Base64.getDecoder().decode(base64.getBytes());
}
/**
* 二进制数据编码为BASE64字符串
*/
public static String encode(byte[] bytes) throws Exception {
return new String(Base64.getEncoder().encode(bytes));
}
}
MD5
/**
* MD5简单加密
*/
public static String getMD5String(String stringText) {
try {
// 生成一个MD5加密计算摘要
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
// 计算md5函数
messageDigest.update(stringText.getBytes());
// digest()最后确定返回md5 hash值,返回值为8位字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符
byte[] digest = messageDigest.digest();
// BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示;得到字符串形式的hash值
//参数一signum代表封装的结果为正,0, 负,相当于标志位;
//一个byte是八位二进制,也就是2位十六进制字符(2的8次方等于16的2次方)
return new BigInteger(1,digest).toString(16).toUpperCase();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
SHA1
public static String getSha1String(String str) {
try {
// 生成一个Sha1加密计算摘要
MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
// 计算Sha1函数
messageDigest.update(str.getBytes("UTF-8"));
// digest()最后确定返回Sha1 hash值
byte[] digest = messageDigest.digest();
return new BigInteger(1, digest).toString(16).toUpperCase();
} catch (Exception e) {
return null;
}
}
AES、DES
/**
* 创建密匙
*
* @param algorithm 加密算法,可用 AES,DES,DESede,Blowfish
* @return SecretKey 秘密(对称)密钥
*/
public static SecretKey createSecretKey(String algorithm) {
// 声明KeyGenerator对象
KeyGenerator keygen;
// 声明 密钥对象
SecretKey deskey = null;
try {
// 返回生成指定算法的秘密密钥的 KeyGenerator 对象
keygen = KeyGenerator.getInstance(algorithm);
// 生成一个密钥
deskey = keygen.generateKey();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
// 返回密匙
return deskey;
}
/**
* 根据相应的加密算法、密钥、源文件进行加密,返回加密后的文件
*
* @param Algorithm 加密算法:DES,AES
* @return
*/
public static String encrypt(String Algorithm, SecretKey key, String info) {
// 定义要生成的密文
byte[] cipherByte = null;
try {
// 得到加密/解密器
Cipher c1 = Cipher.getInstance(Algorithm);
// 用指定的密钥和模式初始化Cipher对象
// 参数:(ENCRYPT_MODE, DECRYPT_MODE, WRAP_MODE,UNWRAP_MODE)
c1.init(Cipher.ENCRYPT_MODE, key);
// 对要加密的内容进行编码处理,
cipherByte = c1.doFinal(info.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
// 返回密文的十六进制形式
return new BigInteger(1, cipherByte).toString(16).toUpperCase();
}
/**
* 根据相应的解密算法、密钥和需要解密的文本进行解密,返回解密后的文本内容
* @param key 秘钥
* @param sInfo 加密后的数据
* @return
*/
public static String decrypt(String Algorithm, SecretKey key, String sInfo) {
try {
byte[] cipherByte = null;
if (Algorithm == null || key == null) {
throw new Exception("不可以为空");
}
// 得到加密/解密器
Cipher c1 = Cipher.getInstance(Algorithm);
// 用指定的密钥和模式初始化Cipher对象
c1.init(Cipher.DECRYPT_MODE, key);
// 对要解密的内容进行编码处理
cipherByte = c1.doFinal(hex2byte(sInfo));
return new String(cipherByte);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 十六进制字符串转化为2进制
*/
public static byte[] hex2byte(String strhex) {
if (strhex == null) {
return null;
}
int l = strhex.length();
if (l % 2 == 1) {
return null;
}
byte[] b = new byte[l / 2];
for (int i = 0; i != l / 2; i++) {
b[i] = (byte) Integer.parseInt(strhex.substring(i * 2, i * 2 + 2), 16);
}
return b;
}
使用方法:
//使用方法
public static void main(String[] args) {
// 生成一个DES算法的密匙
SecretKey desKey1 = createSecretKey("DES");
String str1 = encrypt("DES", desKey1, "大都是发的3423432tgsd321");
System.out.println("DES加密后为:" + str1);
使用这个密匙解密
String str1_1 = decrypt("DES", desKey1, str1);
System.out.println("DES解密后为:" + str1_1);
生成一个AES算法的密匙
SecretKey key2 = createSecretKey("AES");
String str2 = encrypt("AES", key2, "大都是发的3423432tgsd321");
System.out.println("AES加密后为:" + str2);
使用这个密匙解密
String str2_2 = decrypt("AES", key2, str2);
System.out.println("AES解密后为:" + str2_2);
}
RSA
/**
* 加密算法RSA
*/
public static final String KEY_ALGORITHM = "RSA";
/**
* 签名算法
*/
public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
/**
* 获取公钥的key
*/
private static final String PUBLIC_KEY = "RSAPublicKey";
/**
* 获取私钥的key
*/
private static final String PRIVATE_KEY = "RSAPrivateKey";
/**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = 117;
/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = 128;
/**
* 用私钥对信息生成数字签名
*/
public static String sign(byte[] data, String privateKey) throws Exception {
byte[] keyBytes = Base64Utils.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(privateK);
signature.update(data);
return Base64Utils.encode(signature.sign());
}
/**
*
* 校验数字签名
*
*
* @param data 已加密数据
* @param publicKey 公钥(BASE64编码)
* @param sign 数字签名
* @return
* @throws Exception
*/
public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
byte[] keyBytes = Base64Utils.decode(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey publicK = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(publicK);
signature.update(data);
return signature.verify(Base64Utils.decode(sign));
}
/**
* 私钥解密
*/
public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception {
byte[] keyBytes = Base64Utils.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateK);
int inputLen = encryptedData.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
}
/**
* 公钥解密
*/
public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) throws Exception {
byte[] keyBytes = Base64Utils.decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicK);
int inputLen = encryptedData.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
return decryptedData;
}
/**
* 公钥加密
*/
public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
byte[] keyBytes = Base64Utils.decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
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[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
}
/**
* 私钥加密
*/
public static byte[] encryptByPrivateKey(byte[] data, String privateKey) throws Exception {
byte[] keyBytes = Base64Utils.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
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[] encryptedData = out.toByteArray();
out.close();
return encryptedData;
}
/**
*
* 生成密钥对(公钥和私钥)
*
*
* @return
* @throws Exception
*/
public static Map genKeyPair() 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 keyMap = new HashMap(2);
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
}
/**
* 获取私钥
*/
public static String getPrivateKey(Map keyMap) throws Exception {
Key key = (Key) keyMap.get(PRIVATE_KEY);
return Base64Utils.encode(key.getEncoded());
}
/**
* 获取公钥
*/
public static String getPublicKey(Map keyMap) throws Exception {
Key key = (Key) keyMap.get(PUBLIC_KEY);
return Base64Utils.encode(key.getEncoded());
}
使用方法
public static void main(String[] args) throws Exception {
//生成密钥对(公钥和私钥)
Map keyPairs = genKeyPair();
String privateKey = getPrivateKey(keyPairs);
String publicKey = getPublicKey(keyPairs);
System.out.println("私钥:" + privateKey);
System.out.println("公钥:" + publicKey);
// 公钥加密,私钥解密
String content = "123456的高发水电费幅度好大个符号觉得";
byte[] encryptedData = encryptByPublicKey(content.getBytes(Charset.defaultCharset()), publicKey);
byte[] decryptedData = decryptByPrivateKey(encryptedData, privateKey);
System.out.println(new String(decryptedData));
// 数字签名验证
// 私钥签名,生产一个key
String sign = sign(encryptedData, privateKey);
// 公钥验证
boolean verify = verify(encryptedData, publicKey, sign);
System.out.println("内容是否安全:" + verify);
// 私钥加密,公钥解密
content = "哈哈哈哈哈哈哈";
byte[] encryptedData2 = encryptByPrivateKey(content.getBytes(Charset.defaultCharset()), privateKey);
byte[] decryptedData2 = decryptByPublicKey(encryptedData2, publicKey);
System.out.println(new String(decryptedData2));
}
DSA
public static final String KEY_ALGORITHM = "DSA";
public static final String DEFAULT_SEED = "987654321"; //默认种子
public static final String PUBLIC_KEY = "DSAPublicKey";
public static final String PRIVATE_KEY = "DSAPrivateKey";
/**
* 生成密钥
*
* @param seed 种子
* @return 密钥对象
* @throws Exception
*/
public static Map initKey(String seed) throws Exception {
System.out.println("生成密钥");
KeyPairGenerator keygen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
SecureRandom secureRandom = new SecureRandom();
secureRandom.setSeed(seed.getBytes());
//Modulus size must range from 512 to 1024 and be a multiple of 64
keygen.initialize(1024, secureRandom);
KeyPair keys = keygen.genKeyPair();
PrivateKey privateKey = keys.getPrivate();
PublicKey publicKey = keys.getPublic();
Map map = new HashMap(2);
map.put(PUBLIC_KEY, publicKey);
map.put(PRIVATE_KEY, privateKey);
return map;
}
/**
* 生成默认密钥
*
* @return 密钥对象
* @throws Exception
*/
public static Map initKey() throws Exception {
return initKey(DEFAULT_SEED);
}
/**
* 取得私钥
*
* @param keyMap
* @return
* @throws Exception
*/
public static String getPrivateKey(Map keyMap) throws Exception {
Key key = (Key) keyMap.get(PRIVATE_KEY);
return encryptBASE64(key.getEncoded()); //base64加密私钥
}
/**
* 取得公钥
*
* @param keyMap
* @return
* @throws Exception
*/
public static String getPublicKey(Map keyMap) throws Exception {
Key key = (Key) keyMap.get(PUBLIC_KEY);
return encryptBASE64(key.getEncoded()); //base64加密公钥
}
/**
* 用私钥对信息进行数字签名
*
* @param data 加密数据
* @param privateKey 私钥-base64加密的
* @return
* @throws Exception
*/
public static String sign(byte[] data, String privateKey) throws Exception {
System.out.println("用私钥对信息进行数字签名");
byte[] keyBytes = decryptBASE64(privateKey);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey priKey = factory.generatePrivate(keySpec);//生成 私钥
//用私钥对信息进行数字签名
Signature signature = Signature.getInstance(KEY_ALGORITHM);
signature.initSign(priKey);
signature.update(data);
return encryptBASE64(signature.sign());
}
/**
* BASE64Encoder 加密
*
* @param data 要加密的数据
* @return 加密后的字符串
*/
private static String encryptBASE64(byte[] data) throws Exception {
String encode = Base64Utils.encode(data);
return encode;
}
/**
* BASE64Decoder 解密
*
* @param data 要解密的字符串
* @return 解密后的byte[]
* @throws Exception
*/
private static byte[] decryptBASE64(String data) throws Exception {
byte[] buffer = Base64Utils.decode(data);
return buffer;
}
/**
* 校验数字签名
*
* @param data 加密数据
* @param publicKey
* @param sign 数字签名
* @return
* @throws Exception
*/
public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
byte[] keyBytes = decryptBASE64(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey pubKey = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance(KEY_ALGORITHM);
signature.initVerify(pubKey);
signature.update(data);
return signature.verify(decryptBASE64(sign)); //验证签名
}
使用方法:
public static void main(String[] args) throws Exception {
String str ="1245";
byte[] data = str.getBytes();
Map keyMap = initKey();// 构建密钥
PublicKey publicKey = (PublicKey) keyMap.get(PUBLIC_KEY);
PrivateKey privateKey = (PrivateKey) keyMap.get(PRIVATE_KEY);
System.out.println("私钥format:" + privateKey.getFormat());
System.out.println("公钥format:" + publicKey.getFormat());
// 产生签名
String sign = sign(data, getPrivateKey(keyMap));
System.out.println(sign);
// 验证签名
boolean verify = verify(data, getPublicKey(keyMap), sign);
System.err.println("经验证 数据和签名匹配:" + verify);
}