常用加密算法
加密算法分类
加密算法按是否可逆分为单向加密和双向加密。
单向加密
单向加密是不可逆的,也就是说只能进行加密,不能进行解密。通常用来传输或者存储敏感数据,如用户名、密码等。单向加密原则上不可破解,网络上所谓的破解实际上都属于碰撞,就是把常见的明文进行加密成密文后将明文和密文存储起来,然后逆向查询得到明文。常见的单向加密算法有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; } }