可逆与不可逆算法,对称加密与非对称加密算法总结
文章目录
- 1. 加密算法的种类
- 2. 不可逆加密算法
- ①:MD5
- ②:HMAC系列
- ③:SHA系列
- 3. 可逆加密算法
- 1. 对称加密
- ①:DES
- ②:3DES
- ③:AES
- 2. 非对称加密
- ①:RSA
- 4. Base64编码
- 5. BCrypt
1. 加密算法的种类
加密算法分为可逆、不可逆加密算法。而不可逆加密算法又分为对称加密和非对称加密
- 不可逆加密:不可逆加密算法最大的特点就是不需要密钥,但是
HMAC
是需要密钥的!- 常见的不可逆加密算法有
MD5
,HMAC
,SHA1
、SHA-224
、SHA-256
、SHA-384
,和SHA-512
。其中SHA-224、SHA-256、SHA-384,和SHA-512我们可以统称为SHA2
加密算法,SHA加密算法的安全性要比MD5更高,而SHA2加密算法比SHA1的要高。其中SHA后面的数字表示的是加密后的字符串长度,SHA1默认会产生一个160
位的信息摘要。 - 由于这些加密都是不可逆的,因此比较常用的场景就是用户密码加密,其验证过程就是通过比较两个加密后的字符串是否一样来确认身份的。网上也有很多自称是可以破解MD5密码的网站,其原理也是一样,就是有一个巨大的资源库,存放了许多字符串及对应的MD5加密后的字符串,通过你输入的MD5加密串来进行比较,如果过你的密码复杂度比较低,还是有很大机率验证出来的。
- 常见的不可逆加密算法有
- 可逆加密:数据的加密和解密都需要使用秘钥操作
- 对称加密:常见的对称加密算法有
DES
、3DES
、AES128
、AES192
、AES256
- 非对称加密 :常见的非对称加密有
RSA
、SM2
,RS256 (采用SHA-256 的 RSA 签名)
- 对称加密:常见的对称加密算法有
- Base64转码:把字符串转换成以“
==
”结尾的字符串。如:Z38cPD5XbiPZ41LKQmhZAw==
!
2. 不可逆加密算法
①:MD5
MD5 信息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个
128
位(16字节)的散列值(hash value),用于确保信息传输完整一致。
MD5算法有以下特点:
- 压缩性:无论数据长度是多少,计算出来的MD5值长度相同
- 容易计算性:由原数据容易计算出MD5值
- 抗修改性:即便修改一个字节,计算出来的MD5值也会巨大差异
- 抗碰撞性:知道数据和MD5值,很小概率找到相同MD5值相同的原数据。
public static String md5(String text) {MessageDigest messageDigest = null;try {messageDigest = MessageDigest.getInstance("MD5");} catch (NoSuchAlgorithmException e) {e.printStackTrace();}byte[] bytes = messageDigest.digest(text.getBytes());//也可以使用base64转码成字符串// return Base64.getEncoder().encodeToString(bytes);//使用 Hex转码return Hex.encodeHexString(bytes);}
②:HMAC系列
HMAC算法更像是一种加密算法,它引入了密钥,其安全性已经不完全依赖于所使用的Hash算法。
HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code)的缩写,由H.Krawezyk,M.Bellare,R.Canetti于1996年提出的一种基于Hash函数和密钥进行消息认证的方法,并于1997年作为RFC2104被公布,并在IPSec和其他网络协议(如SSL)中得以广泛应用,现在已经成为事实上的Internet安全标准。它可以与任何迭代散列函数捆绑使用。
public static String hmacSha256(String text, SecretKeySpec sk) {Mac mac = null;try {mac = Mac.getInstance("HmacSHA256");} catch (NoSuchAlgorithmException e) {e.printStackTrace();}try {mac.init();} catch (Exception e) {e.printStackTrace();}byte[] rawHmac = mac.doFinal(text.getBytes());return Base64.getEncoder().encodeToString(rawHmac);}
③:SHA系列
安全散列算法(英语:Secure Hash Algorithm,缩写为SHA)是一个密码散列函数家族,是FIPS所认证的安全散列算法。能计算出一个数字消息所对应到的,长度固定的字符串(又称消息摘要)的算法。且若输入的消息不同,它们对应到不同字符串的机率很高。SHA-1加密算法有碰撞的可能性,虽然很小。
public static String sha256(String text) {MessageDigest messageDigest = null;try {messageDigest = MessageDigest.getInstance("SHA-256");} catch (NoSuchAlgorithmException e) {e.printStackTrace();}byte[] bytes = messageDigest.digest(text.getBytes());return Hex.encodeHexString(bytes);}
3. 可逆加密算法
可逆加密算法又分为 对称加密 和 分对称加密
1. 对称加密
对称加密算法是应用比较早的算法,在数据加密和解密的时用的都是同一个密钥,这就造成了密钥管理困难的问题。常见的对称加密算法有DES
、3DES
、AES128
、AES192
、AES256
(默认安装的 JDK 尚不支持 AES256,需要安装对应的 jce 补丁进行升级 jce1.7,jce1.8)。其中AES后面的数字代表的是密钥长度。对称加密算法的安全性相对较低,比较适用的场景就是内网环境中的加解密。
①:DES
DES是对称加密算法领域中的典型算法,其密钥默认长度为56位。
// 加密public static String encrypt(byte[] dataSource, String password){try {SecureRandom random = new SecureRandom();DESKeySpec desKeySpec = new DESKeySpec(password.getBytes());//创建一个密匙工厂,然后用它把DESKeySpec转换成 SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);//Cipher对象实际完成加密操作 Cipher cipher = Cipher.getInstance("DES");//用密匙初始化Cipher对象 cipher.init(Cipher.ENCRYPT_MODE, secretKey, random);//正式执行加密操作 return Base64.encodeBase64String(cipher.doFinal(dataSource));} catch (Throwable e) {e.printStackTrace();} return null;}// 解密public static String decrypt(String src, String password) throws Exception{// DES算法要求有一个可信任的随机数源 SecureRandom random = new SecureRandom();// 创建一个DESKeySpec对象 DESKeySpec desKeySpec = new DESKeySpec(password.getBytes());// 创建一个密匙工厂 SecretKeyFactory keyFactory= SecretKeyFactory.getInstance("DES");// 将DESKeySpec对象转换成SecretKey对象 SecretKey secretKey = keyFactory.generateSecret(desKeySpec);// Cipher对象实际完成解密操作 Cipher cipher = Cipher.getInstance("DES");// 用密匙初始化Cipher对象 cipher.init(Cipher.DECRYPT_MODE, secretKey, random);// 真正开始解密操作 return new String(cipher.doFinal(Base64.decodeBase64(src)));}
②:3DES
3DES(即Triple DES)是DES向AES过渡的加密算法,它使用3条56位的密钥对数据进行三次加密。是DES的一个更安全的变形。它以DES为基本模块,通过组合分组方法设计出分组加密算法。比起最初的DES,3DES更为安全。密钥长度默认为168位,还可以选择128位。
// 加密public static String encryptThreeDESECB(String src, String key) {try{DESedeKeySpec dks = new DESedeKeySpec(key.getBytes("UTF-8"));SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");SecretKey securekey = keyFactory.generateSecret(dks);Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");cipher.init(Cipher.ENCRYPT_MODE, securekey);byte[] b = cipher.doFinal(src.getBytes("UTF-8"));String ss = new String(Base64.encodeBase64(b));ss = ss.replaceAll("\\+", "-");ss = ss.replaceAll( "/", "_");return ss;} catch(Exception ex){ex.printStackTrace();return src;}}// 解密public static String decryptThreeDESECB(String src, String key) {try{src = src.replaceAll("-", "+");src = src.replaceAll("_", "/");byte[] bytesrc = Base64.decodeBase64(src.getBytes("UTF-8"));// --解密的keyDESedeKeySpec dks = new DESedeKeySpec(key.getBytes("UTF-8"));SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");SecretKey securekey = keyFactory.generateSecret(dks);// --Chipher对象解密Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");cipher.init(Cipher.DECRYPT_MODE, securekey);byte[] retByte = cipher.doFinal(bytesrc);return new String(retByte, "UTF-8");} catch(Exception ex){ex.printStackTrace();return src;}}
③:AES
AES高级数据加密标准,能够有效抵御已知的针对DES算法的所有攻击,默认密钥长度为128位,还可以供选择192位,256位。这里顺便提一句这个位指的是bit。
private static final String defaultCharset = "UTF-8";private static final String KEY_AES = "AES";private static final String KEY_MD5 = "MD5";private static MessageDigest md5Digest;static {try {md5Digest = MessageDigest.getInstance(KEY_MD5);} catch (NoSuchAlgorithmException e) {}}/*** 加密*/public static String encrypt(String data, String key) {return doAES(data, key, Cipher.ENCRYPT_MODE);}/*** 解密*/public static String decrypt(String data, String key) {return doAES(data, key, Cipher.DECRYPT_MODE);}/*** 加解密*/private static String doAES(String data, String key, int mode) {try {boolean encrypt = mode == Cipher.ENCRYPT_MODE;byte[] content;if (encrypt) {content = data.getBytes(defaultCharset);} else {content = Base64.decodeBase64(data.getBytes());}SecretKeySpec keySpec = new SecretKeySpec(md5Digest.digest(key.getBytes(defaultCharset)), KEY_AES);Cipher cipher = Cipher.getInstance(KEY_AES);// 创建密码器cipher.init(mode, keySpec);// 初始化byte[] result = cipher.doFinal(content);if (encrypt) {return new String(Base64.encodeBase64(result));} else {return new String(result, defaultCharset);}} catch (Exception e) {}return null;}
2. 非对称加密
非对称加密算法有两个密钥,这两个密钥完全不同但又完全匹配。只有使用匹配的一对公钥和私钥,才能完成对明文的加密和解密过程。常见的非对称加密有RSA、SM2等。
①:RSA
RSA密钥至少为500位长,一般推荐使用1024位
//非对称密钥算法
public static final String KEY_ALGORITHM = "RSA";/*** 密钥长度,DH算法的默认密钥长度是1024* 密钥长度必须是64的倍数,在512到65536位之间*/
private static final int KEY_SIZE = 1024;
//公钥
private static final String PUBLIC_KEY = "RSAPublicKey";
//私钥
private static final String PRIVATE_KEY = "RSAPrivateKey";
/*** 初始化密钥对** @return Map 甲方密钥的Map*/
public static Map<String, Object> initKey() throws Exception {//实例化密钥生成器KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);//初始化密钥生成器keyPairGenerator.initialize(KEY_SIZE);//生成密钥对KeyPair keyPair = keyPairGenerator.generateKeyPair();//甲方公钥RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();//甲方私钥RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();//将密钥存储在map中Map<String, Object> keyMap = new HashMap<String, Object>();keyMap.put(PUBLIC_KEY, publicKey);keyMap.put(PRIVATE_KEY, privateKey);return keyMap;
}
/*** 私钥加密** @param data 待加密数据* @param key 密钥* @return byte[] 加密数据*/
public static byte[] encryptByPrivateKey(byte[] data, byte[] key) throws Exception {//取得私钥PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);//生成私钥PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);//数据加密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, privateKey);return cipher.doFinal(data);
}/*** 公钥加密** @param data 待加密数据* @param key 密钥* @return byte[] 加密数据*/
public static byte[] encryptByPublicKey(byte[] data, byte[] key) throws Exception {//实例化密钥工厂KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);//初始化公钥//密钥材料转换X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);//产生公钥PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);//数据加密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, pubKey);return cipher.doFinal(data);
}/*** 私钥解密** @param data 待解密数据* @param key 密钥* @return byte[] 解密数据*/
public static byte[] decryptByPrivateKey(byte[] data, byte[] key) throws Exception {//取得私钥PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);//生成私钥PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);//数据解密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, privateKey);return cipher.doFinal(data);
}/*** 公钥解密** @param data 待解密数据* @param key 密钥* @return byte[] 解密数据*/
public static byte[] decryptByPublicKey(byte[] data, byte[] key) throws Exception {//实例化密钥工厂KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);//初始化公钥//密钥材料转换X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);//产生公钥PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);//数据解密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, pubKey);return cipher.doFinal(data);
}/*** 取得私钥** @param keyMap 密钥map* @return byte[] 私钥*/
public static byte[] getPrivateKey(Map<String, Object> keyMap) {Key key = (Key) keyMap.get(PRIVATE_KEY);return key.getEncoded();
}/*** 取得公钥** @param keyMap 密钥map* @return byte[] 公钥*/
public static byte[] getPublicKey(Map<String, Object> keyMap) throws Exception {Key key = (Key) keyMap.get(PUBLIC_KEY);return key.getEncoded();
}
4. Base64编码
Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一。Base64编码可用于在HTTP环境下传递较长的标识信息。采用Base64Base64编码解码具有不可读性,即所编码的数据不会被人用肉眼所直接看到。注意:Base64只是一种编码方式,不算加密方法。
java.util.Base64.getEncoder().encodeToString(bytes);
在线Base64编码工具:http://www.jsons.cn/img2base64/
5. BCrypt
在系统架构中,对于用户密码的保护,通常都会进行加密。我们通常对密码进行加密,然后存放在数据库中,在用户进行登录的时候,将其输入的密码进行加密然后与数据库中存放的密文进行比较,以验证用户密码是否正确。 目前,MD5和BCrypt比较流行。相对来说,BCrypt比MD5更安全。
//这个是盐 29个字符,随机生成String gensalt = BCrypt.gensalt();System.out.println(gensalt);//根据盐对密码进行加密String password = BCrypt.hashpw("password666", gensalt); System.out.println(password);//加密后的字符串前29位就是盐//实现对密码的校验。BCrypt不支持反运算,只支持密码校验。boolean checkpw = BCrypt.checkpw("password666", "$2a$10$61ogZY7EXsMDWeVGQpDq3OBF1.phaUu7.xrwLyWFTOu8woE08zMIW");System.out.println(checkpw);
BCrypt的使用:以登录为例
对密码加密,并入库
@Override public void add(User user){String password = BCrypt.hashpw(User.getPassword(), BCrypt.gensalt());user.setPassword(password); userMapper.insert(user); //加密结果入库 }
登录时,校验密码是否正确
@Overridepublic boolean login(User user) {//根据登录名查询管理员User u1=new User();u1.setLoginName(User.getLoginName());u1.setStatus("1");User u2 = UserMapper.selectOne(u1);//数据库查询出的对象if(u2==null){return false;}else{//验证密码, Bcrypt为spring的包, 第一个参数为明文密码, 第二个参数为密文密码return BCrypt.checkpw(u1.getPassword(),u2.getPassword());}}
可逆与不可逆算法,对称加密与非对称加密算法总结相关推荐
- 对称加密和非对称加密算法工作过程详解
非对称加密算法: 加密和解密使用不同的密钥.公钥只能用来加密,而私钥只能用来解密.私钥由用户自己拥有.公钥公开配送,只要有需求即可获得. 优点: 算法安全性高,公钥公开,私钥自己保存 缺点: 加密和解 ...
- 对称加密和非对称加密算法分类,国密算法分类。
对称加密算法 对称加密算法加密和解密使用的是同一个密钥.常用的对称加密算法包括:DES.3DES.AES.RC4.RC5.RC6. 非对称加密算法 指加密和解密使用不同密钥的加密算法,也称为公私钥加密 ...
- 【计算机网络】对称加密、非对称加密和Hash加密的介绍和区别
目录 一.对称加密(Symmetric Cryptography) 优缺点 二.非对称加密(asymmetric Cryptography) 优缺点 三.Hash加密算法(摘要算法) 对称加密算法的加 ...
- JackHttp -- 浅谈编码、加密(对称加密,非对称加密,Hash算法)
如果你还不清楚 JackHttp 是什么,请戳这里!!! JackHttp 是一个网络框架系列,为什么还要分享编码和加密呢?主要有如下几个原因: HTTP 在网络传输过程中是明文的. HTTP 在网络 ...
- 对称加密、非对称加密和散列算法
一.什么是对称加密技术? 对称加密采用了对称密码编码技术,它的特点是文件加密和解密使用相同的密钥.信息接收双方都需事先知道密匙和加解密算法,且其密匙是相同的,之后便是对数据进行加解密了.对称加密算法用 ...
- 安卓中的对称加密,非对称加密,MD5加密的算法
转自:http://blog.csdn.net/fengkaungdewoniu/article/details/52846025 安卓中使用的加密算法可以说有三种:对称加密.非对称加密,及MD5加密 ...
- 通俗解释对称加密、非对称加密、散列算法与PKI
这是我前些年写在51的,现在转过来,其实是CISSP的学习笔记,用自己的语言组织起来的,用通俗的话说明对称加密.非对称加密.散列算法.PKI(CA)到底都是干啥的.OK,进入主题: 密码学要解决的问题 ...
- 对称加密、非对称加密深度解析
密码学的发展 加密的发展史随着人类的进化逐步复杂.严谨也更安全,对于早期的移位和字母对应等加密方式我们不难理解. 移位 : 比如恺撒密码, 简单点说将 26个英文字母的顺序打乱,得到一个新的字母顺序, ...
- 网络协议从入门到底层原理(7)网络安全 - 常见攻击、单向散列函数、对称加密、非对称加密、混合密码系统、数字签名、证书
网络安全 网络层 - ARP欺骗 DoS.DDoS 介绍与防御 传输层 - SYN洪水攻击(SYN flooding attack) 传输层 - LAND攻击 应用层 - DNS劫持.HTTP劫持 H ...
最新文章
- myeclipse tomcat内存溢出解决方法
- 小森生活一直服务器维护,《小森生活》怎么处理断线黑屏的问题 连接不上服务器解决办法...
- 快慢法判断单链表中是否有循环链表
- 类中构造函数、析构函数与赋值函数的重写
- nginx 集群部署_Nginx Ingress on TKE 部署最佳实践
- 调查 1621 万互联网人:发现技术人基本是男性,还一半都单身
- 【个人网站搭建教程】阿里云服务器+宝塔+wordpress
- 说明 RISC 和 CISC 指令系统的区别?
- indesign教程,如何创建对齐参考线?
- 使用TypeScript开发ReactNative应用的简单示例
- Android studio打包apk
- 网络安全从业者“行话”
- 电脑照片尺寸如何调整成自己想要的
- 【雷达通信】基于matlab粒子群算法优化综合微带天线阵列方向图【含Matlab源码 1967期】
- 草莓电吉他音源 Orange Tree Samples Evolution Strawberry Kontakt
- js解析json字符串为json对象,js解析json的6种方法
- Django(10)-模板层的变量和标签
- win10的ie11正确卸载与重新安装
- 基于pymongo的学生信息考勤管理系统开发学习笔记之mongo篇
- Arduino+Proteus 模拟摩尔斯码求救信号
热门文章
- C# 操作Sqlite
- Dw序号列表如何通过html语言加,使用DW软件实现html编码转换的详细步骤
- 在html中单选选择器,已选中单选按钮标签的CSS选择器
- 怎么调出matlab的函数,matlab定义函数【搞定方法】
- xss绕过字符过滤_XSS绕过实战练习
- 【狂神JAVA】MyBatis笔记
- 阿里巴巴获评《福布斯》全球最有投资价值公司
- 7.2. cvs login | logout
- DBA必知的mysql备份与还原的几大方法
- MyBatis学习总结(13)——Mybatis查询之resultMap和resultType区别