在开发的过程中避免不了使用加密进行操作,例如密码,文件加密,软件激活,因为加密算法快上百种就不细说了,讲解下常用算法
简介
算法都是不能逆推的,既然不能破解为什么不安全,因为可以碰撞,就是加密算法进行反向查询,案例:山东大学王小云教授发现了md5的碰撞原理。具体碰撞过程参考:链接
算法 | 简介 | 算法类型 | 安全系数 | 应用场景 |
---|---|---|---|---|
base64 | Base64编码是从二进制到字符的过程,可以互相转换,其实不是算法 | 无 | ☆ | 图片存储,参数非原始显示 |
md5 | message-digest algorithm 5(信息-摘要算法)MD5哈希函数将任意长度的二进制字符串映射为固定长度的小型二进制字符串。由32位16进制组成散列算法,或者叫做哈希算法 (Hash算法)md5在md4基础上改进 | 哈希算法 | ★★ | 文件下载签名校验完整性 |
SHA-1 | 安全哈希算法(Secure Hash Algorithm)sha-1是160位(160bit)的哈希值 | 哈希算法 | ★★☆ | 文件下载签名校验完整性 |
SHA-2 | 安全哈希算法(Secure Hash Algorithm)算法为SHA-224、SHA-256、SHA-384和SHA-512 | 哈希算法 | ★★★ | 文件下载签名校验完整性 |
HMAC | HMAC是密钥相关的哈希运算消息认证码,HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。(HmacMD5,HmacSHA1,HmacSHA224,HmacSHA256,HmacSHA384,HmacSHA512) | 哈希算法 | ★★★☆ | 密码 |
PBKDF2 | PBKDF2应用一个伪随机函数以导出密钥。导出密钥的长度本质上是没有限制的(但是,导出密钥的最大有效搜索空间受限于基本伪随机函数的结构)(PBKDF2WithHmacSHA1,PBKDF2WithHmacSHA256,PBKDF2WithHmacSHA512) | 哈希算法 | ★★★★ | 密码 |
BCrypt | bcrypt是一个跨平台的文件加密工具。由它加密的文件可在所有支持的操作系统和处理器上进行转移。它的口令必须是8至56个字符,并将在内部被转化为448位的密钥。 | Blowfish算法 | ★★★★ | 主要文件加密 |
Scrypt | scrpyt算法是由著名的FreeBSD黑客 Colin Percival为他的备份服务 Tarsnap开发的,当初的设计是为了降低CPU负荷,尽量少的依赖cpu计算,利用CPU闲置时间进行计算,因此scrypt不仅计算所需时间长,而且占用的内存也多,使得并行计算多个摘要异常困难,因此利用rainbow table进行暴力攻击更加困难。 | 密钥派生函数 参考:链接 | ★★★★☆ | 主要虚拟货币,密码,加密 |
算法可靠性参考:链接
- maven
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.12</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-crypto</artifactId>
<version>1.0.0</version>
</dependency>
官方参考 :http://commons.apache.org/proper/commons-codec/
官方参考 :http://commons.apache.org/proper/commons-crypto/
apache提供的加密没有BCrypt算法官方使用的Scrypt算法
说下commons-codec的简单使用其它实例参考官方
/**
* 编码base64
*
* @param data 需要编码的数据 如果是对象需要转换JSON
* @return 编码之后的内容
*/
public static String encodeBase64(Object data) {
try {
if (Objects.nonNull(data)) {
return Base64.encodeBase64String(data.toString().getBytes(StandardCharsets.UTF_8));
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 解码base64
*
* @param data 解码的内容 如果是对象需要转换JSON
* @return 解码之后的数据
*/
public static String decodeBase64(Object data) {
try {
if (Objects.nonNull(data)) {
return Arrays.toString(Base64.decodeBase64(data.toString()));
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
算法可以嵌套多个,提供多密匙,使加密更加可靠。
PBKDF2算法在spring security 密码加密中有使用
//spring securiy 默认算法
//通过此工厂PasswordEncoderFactories.createDelegatingPasswordEncoder();调用
public class PasswordEncoderFactories {
@SuppressWarnings("deprecation")
public static PasswordEncoder createDelegatingPasswordEncoder() {
String encodingId = "bcrypt";
Map<String, PasswordEncoder> encoders = new HashMap<>();
encoders.put(encodingId, new BCryptPasswordEncoder());
encoders.put("ldap", new org.springframework.security.crypto.password.LdapShaPasswordEncoder());
encoders.put("MD4", new org.springframework.security.crypto.password.Md4PasswordEncoder());
encoders.put("MD5", new org.springframework.security.crypto.password.MessageDigestPasswordEncoder("MD5"));
encoders.put("noop", org.springframework.security.crypto.password.NoOpPasswordEncoder.getInstance());
encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
encoders.put("scrypt", new SCryptPasswordEncoder());
encoders.put("SHA-1", new org.springframework.security.crypto.password.MessageDigestPasswordEncoder("SHA-1"));
encoders.put("SHA-256", new org.springframework.security.crypto.password.MessageDigestPasswordEncoder("SHA-256"));
encoders.put("sha256", new org.springframework.security.crypto.password.StandardPasswordEncoder());
return new DelegatingPasswordEncoder(encodingId, encoders);
}
private PasswordEncoderFactories() {}
}
如果你的项目集成security写个简单例子:
//strength强度,密码迭代次数 between 4 and 31
BCryptPasswordEncoder bCrypt = new BCryptPasswordEncoder(BCryptPasswordEncoder.BCryptVersion.$2Y, 31, random);
//编码,BCryptVersion.$2Y默认会作为盐(密匙)参考源码bCrypt.encode
String encode = bCrypt.encode("123456");
//校验
bCrypt.matches("123456",encode);