1.å¦ä½è®¡ç®InputstreamçMD5
2.java.security.messagedigest.getinstance 线ç¨å®å
¨å
3.爆破专栏丨Spring Security系列教程之SpringSecurity中的密码加密
4.jsp md5 å¨ç½è®ºå
å¦ä½è®¡ç®InputstreamçMD5
é¦å ï¼æç®åçæ¹å¼å°±æ¯æä½ ç两è¡ä»£ç ç»åèµ·æ¥ï¼å ä¿åæ件ï¼å读åæ件æµè®¡ç®MD5ï¼
public static String copyInputStreamToFileAndGetMd5Hex(InputStream inputStream, File file) throws IOException {
FileUtils.copyInputStreamToFile(inputStream, file);
return DigestUtils.md5Hex(new FileInputStream(file));
}
å½ç¶è¿æ ·åè¦å¯¹åä¸ä¸ªæµè¯»å两次ï¼æ¾å¾ä¸å¤ä½ç¢³ç¯ä¿ã
æ¤æ¶å¯ä»¥çä¸DigestUtilsæºç ï¼è¿½å ¶æ ¹æº¯å ¶æºå¯ä»¥çå°ï¼
public static MessageDigest updateDigest(final MessageDigest digest, final InputStream data) throws IOException {
final byte[] buffer = new byte[STREAM_BUFFER_LENGTH];
int read = data.read(buffer, 0, STREAM_BUFFER_LENGTH);
while (read > -1) {
digest.update(buffer, 0, read);
read = data.read(buffer, 0, STREAM_BUFFER_LENGTH);
}
return digest;
}
ä¹ä¸æ¯å¤é«çº§çææ¯ï¼å°±æ¯ææ´ä¸ªInputStreamææé¿åº¦çåèæ°ç»é个MD5ã
åççFileUtils.copyInputStreamToFileæºç çè¿½æ ¹æº¯æºå®ç°ï¼
public static long copyLarge(InputStream input, OutputStream output, byte[] buffer) throws IOException {
long count;
int n;
for(count = 0L; -1 != (n = input.read(buffer)); count += (long)n) {
output.write(buffer, 0, n);
}
return count;
}
åæ ·ä¹æ¯è®²InputStreamææçåèæ°ç»ï¼é个åå°ç®æ æ件ä¸ã
é£ä¹ï¼ä¸¤è ç»åèµ·æ¥ä»£ç ä¹å°±å¥½åäºï¼
public static String copyInputStreamToFileAndGetMd5Hex(InputStream inputStream, File file) throws IOException {
MessageDigest digest = DigestUtils.getMd5Digest();
FileOutputStream outputStream = null;
try {
outputStream = new FileOutputStream(file);
byte[] buffer = new byte[];
int read = inputStream.read(buffer);
while (read > -1) {
// 计ç®MD5,顺便åå°æ件
digest.update(buffer, 0, read);
outputStream.write(buffer, 0, read);
read = inputStream.read(buffer);
}
} finally {
IOUtils.closeQuietly(outputStream);
}
return Hex.encodeHexString(digest.digest());
}
java.security.messagedigest.getinstance 线ç¨å®å ¨å
ä¸æ¯çº¿ç¨å®å ¨ç ä½ å¯ä»¥ççæºç
public static MessageDigest getInstance(String algorithm)
throws NoSuchAlgorithmException {
try {
Object[] objs = Security.getImpl(algorithm, "MessageDigest",
(String)null);
if (objs[0] instanceof MessageDigest) {
MessageDigest md = (MessageDigest)objs[0];
md.provider = (Provider)objs[1];
return md;
} else {
MessageDigest delegate =
new Delegate((MessageDigestSpi)objs[0], algorithm);
delegate.provider = (Provider)objs[1];
return delegate;
}
} catch(NoSuchProviderException e) {
throw new NoSuchAlgorithmException(algorithm + " not found");
}
}
è¿é没æä»»ä½æ¶å线ç¨å®å ¨çå®ä¹
爆破专栏丨Spring Security系列教程之SpringSecurity中的密码加密
前言
本文将带您深入Spring Security密码加密机制的学习。Spring Security作为安全框架,自然包含密码加密内容。本篇将详细解释密码加密原理、Spring Security中的处理方案,特别是热血网源源码BCryptPasswordEncoder的应用。此外,还会指导您如何使用BCryptPasswordEncoder进行加密,以及实现多密码加密方案共存。
一. 密码加密简介
散列加密概述:密码加密常采用的信息摘要算法,包括MD5、SHA系列等,将数据压缩成固定长度的字符串。
散列加密原理:通过压缩和混淆数据生成唯一指纹,确保数据安全。拖拉机源码
盐的作用:为增加安全性,密码加密时加入随机盐值,确保即使明文相同,生成的密文也不同。
Spring Security密码处理:支持BCryptPasswordEncoder等方案,确保密码安全。
二. 利用BCryptPasswordEncoder进行加密
编写接口、布林带指标源码配置加密算法、测试运行,实现密码加密。
1. 编写register接口
在UserController中添加register接口,对密码进行加密,注入PasswordEncoder对象。
2. 配置密码加密算法
在Security Config类中,qq号码网站源码配置使用BCryptPasswordEncoder,放行注册接口。
3. 测试运行
启动项目,测试/user/register接口,验证密码加密效果。
4. BCryptPasswordEncoder加解密原理
BCrypt随机生成盐值,确保密码明文相同,会议管理系统 源码密文也不同。比对密码时,先提取盐值,再加密明文,最后对比生成的密文。
三. 利用其他Encoder进行加密实现
1. MessageDigestPasswordEncoder用法
使用MessageDigestPasswordEncoder实现,支持MD5、SHA等算法,配置时需指定算法名称。
2. DelegatingPasswordEncoder用法
利用DelegatingPasswordEncoder实现密码加密方案的动态切换,支持多种加密方式。
四. 源码解析
了解PasswordEncoder接口、默认实现BCryptPasswordEncoder、密码比对原理。
1. PasswordEncoder接口解读
接口定义密码加密和比对方法,实现密码安全。
2. matches()默认执行时机
自动调用matches方法进行密码比对,无需手动编码。
五. 实现多密码加密方案共存
1. 需求背景
项目改造时,需要更新密码加密方案,但不希望用户重新注册。
2. 实现过程
配置DelegatingPasswordEncoder,定义测试接口,测试共存效果。
3. 多密码方案并存实现原理
Spring Security通过配置不同PasswordEncoder实现密码加密方案的灵活管理。
jsp md5 å¨ç½è®ºå
MD5ç®æ³æ¯åºå®çï¼ä¸æ¯è¯´æ人çMD5åå¦å¤çmd5ä¸ä¸æ ·
ä½ æåå¨ç½è®ºåå å¯åçMD5ç ï¼æ¯å¦ä½ å å¯âAAAâ ï¼ç¶åå»æ¾æ åçMD5å å¯AAAï¼å¦æè·å¾çå¯æä¸ä¸æ ·ï¼é£è¯´æå¨ç½è®ºåç³»ç»å¯¹md5è¿è¡äºä¿®æ¹æ2次å å¯ï¼å¦æä½ æ²¡æå¨ç½æºç é£å°±å®å ¨æ²¡æäº
-------------------------------------------
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* é便åçä¸ä¸ªMD5å å¯ åæ°code为åæï¼é»è®¤è¿åå¼ä¸ºMD5çä½å¯æ
*ä½é£è¡å»ææ左端注é符 è¿åå¼å°±æ¯ä½
* */
public String enCodeByMD5(String code) {
String password = code;
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(code.getBytes());
byte b[] = md.digest();
int i;
StringBuffer buf = new StringBuffer("");
for (int offset = 0; offset < b.length; offset++) {
i = b[offset];
if (i < 0)
i += ;
if (i < )
buf.append("0");
buf.append(Integer.toHexString(i));
}
password = buf.toString();//ä½çå å¯
// password = password.substring(8,);//ä½çå å¯
}
catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return password;
}
----------------------------------------
以ä¸ä¸ºMD5å å¯
----------------------------------------
ä¸é¢é£ä¸ªæ¯æèªå·±åçä¸ä¸ªçº¯æ°å¦æ¹æ³å å¯ï¼å¾ç®åï¼æ¨¡ä»¿MD5çä¿¡æ¯æè¦æ³ï¼è¯¥ç®æ³ä¹æ¯ä¸å¯éå å¯ï¼ 尽管ç®æ³å¼ºåº¦ï¼æçï¼é½æ¯ä¸ä¸MD5..ä½æ¯æ¯æ°ç®æ³ï¼æ以ä¸å¯è½ä¼æ穷举æ°æ®åºï¼æºç ä¹æ¯æ第ä¸æ¬¡å¨ç¾åº¦ç¥éä¸åï¼ç®åçå®å ¨æ§åèæ¯MD5é«ä¸äºã
---
public String enCodeByMath(String code) {
int k;
int l;
StringBuffer sbuf = new StringBuffer();
int cl = code.length();
long tempInt1 = 0L;
byte[] tempByte1 = code.getBytes();
byte[] arrayOfByte1 = tempByte1;
int i = 0;
for (int j = arrayOfByte1.length; i < j; ++i) {
byte b = arrayOfByte1[i];
tempInt1 = ((tempInt1 + b + 1L) * (b - cl) - cl * cl) * (b + - cl * cl);
sbuf.append(String.valueOf(Math.abs(tempInt1)));
}
for (i = cl; sbuf.length() < ; ++i)
if (i + 1 < sbuf.length()) {
sbuf.append(sbuf.toString().substring(i, i + 1));
} else
sbuf.append("a");
byte[] tempByte2 = sbuf.toString().getBytes();
int[][] tempInt2 = new int[][];
k = 0;
for (l = 0; l < ; ++l)
for (int j = 0; j < ; ++j) {
tempInt2[l][j] = (tempByte2[k] * cl);
++k;
}
sbuf.delete(0, sbuf.length());
for (l = 0; l < ; ++l)
sbuf.append(Math.abs(tempInt2[l][l] * cl - tempInt2[l][(l + )] * ( - cl)));
String puzzleCode = sbuf.toString();
tempByte2 = null;
tempInt2 = null;
return puzzleCode;
}
irf ..