java程序猿的成长记录之(三)分享一种防猜的加密算法
2017-04-27 16:42
288 查看
在日常开发中,数据库用户表密码的存放一般不会放置明文密码.就算存的是加密后的,相同密码加密后获得的字符串也是相同的.今天博主学习了一种加密算法,每次生成的密文不同 废话少说,开始coding....
生成随机的Byte[]作为salt
// numBytes为想要生成"盐"的长度 private static byte[] generateSalt(int numBytes) { byte[] bytes = new byte[numBytes]; new SecureRandom().nextBytes(bytes); return bytes; }
HTML 解码
//htmlEscaped 为想要加密的字符串 private static String unescapeHtml(String htmlEscaped) { return StringEscapeUtils.unescapeHtml4(htmlEscaped); }
Hex编码
private static String encodeHex(byte[] input) { return new String(Hex.encodeHex(input)); }
Hex解码
private static byte[] decodeHex(String input) { byte[] bytes = null; try { bytes = Hex.decodeHex(input.toCharArray()); } catch (DecoderException e) { e.printStackTrace(); } return bytes; }
对字符串进行散列(精华部分)
/** * iterations sha-1的次数 * salt 参与算法的盐 * input 参与算法的字符串.getBytes() */ private static byte[] digest(byte[] input, byte[] salt, int iterations) { MessageDigest digest = null; try { //这里也可以MD5 digest = MessageDigest.getInstance("SHA-1"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } if (salt != null) { digest.update(salt); } byte[] result = digest.digest(input); for (int i = 1; i < iterations; i++) { digest.reset(); result = digest.digest(result); } return result; }
准备工作完毕,开始进行安全字符串的生成
public static String createSign(String sign) { //将目标字符串进行处理 String plain = unescapeHtml(sign); //生成参与算法的盐 byte[] salt = generateSalt(8); //经过1024次sha-1. byte[] hashStr = digest(plain.getBytes(),salt,1024); //返回密文 return encodeHex(salt) + encodeHex(hashStr); }
由于是单向加密,对生成密文无法解密,所以我们判定方法为将目标字符串再次进行加密看与之前加密过的hash相同与否
/** * sign 目标字符串 * hashSign 已存在的密文 */ public static boolean validateSign(String sign, String hashSign) { String plain = unescapeHtml(sign); //得到上次上次参与算法的盐 byte[] salt = decodeHex(hashSign.substring(0, 16)); byte[] hashStr = digest(plain.getBytes(), salt,1028); return hashSign.equals(encodeHex(salt)+ encodeHex(hashStr)); }
我们来验证下:
public static void main(String[] args) { System.out.println("wisty字符串第一次加密结果:"+createSign("wisty")); System.out.println("wisty字符串第二次加密结果:"+createSign("wisty")); System.out.println("wisty字符串第三次加密结果:"+createSign("wisty")); System.out.println("wisty字符串第四次加密结果:"+createSign("wisty")); } ------------------结果如下-------------- wisty字符串第一次加密结果:8d4b1d479556a3fea133e7ce663d778d5ad47606ea4d02192e174f46 wisty字符串第二次加密结果:8ed8b6bf9860139679a7161c8afd4ebe4dbef6f951231adbd7757e1c wisty字符串第三次加密结果:75a1146425ed57067d22332b11f628ee822e725f625b778231c14162 wisty字符串第四次加密结果:21f513cf5e8f793ee3af9b1f210b08803c5bab614fbd543791e6ba29
public static void main(String[] args) { System.out.println("明密文第一次比较结果:"+validateSign("wisty","8d4b1d479556a3fea133e7ce663d778d5ad47606ea4d02192e174f46")); System.out.println("明密文第二次比较结果:"+validateSign("wisty","8ed8b6bf9860139679a7161c8afd4ebe4dbef6f951231adbd7757e1c")); System.out.println("明密文第三次比较结果:"+validateSign("wisty","75a1146425ed57067d22332b11f628ee822e725f625b778231c14162")); System.out.println("明密文第四次比较结果:"+validateSign("wisty","21f513cf5e8f793ee3af9b1f210b08803c5bab614fbd543791e6ba29")); ------------------结果如下-------------- 明密文第一次比较结果:true 明密文第二次比较结果:true 明密文第三次比较结果:true 明密文第四次比较结果:true
从上面我们可以看到每次生成的密文都不同,通过比较密文指向同一个明文………..
欢迎大家交流学习
相关文章推荐
- java程序猿的成长记录之(二)web中自定义标签tld与业务字典的结合使用感悟
- java程序猿的成长记录之(一)用itext创建并生成pdf
- 分享一下@Override标签背后的小秘密---记录java的思行合一
- 等了三天,终于可以发表了。在这里记录下学习JAVA软件开发成长中的一点一滴
- JAVA学习,记录成长
- 分享Java常用几种加密算法(四种)
- 分享以下编译错误:java.util.concurrent.ExecutionException: java.lang.UnsupportedOperationException的一种解决方法
- java成长记录
- 今天开始,将记录成长,点滴耕耘与您一同分享!
- 偶然间收藏了以为网友的java总结分享,写的非常好,记录一下。
- Python模块学习 ---- fileinput - 成长的点滴,记录与分享 - 博客频道 - CSDN.NET
- 初级程序猿,系统重装之后软件安装心得分享(一JAVA,安卓开发环境安装篇)
- 分享一下@Override标签背后的小秘密---记录java的思行合一
- 积少成多,记录java菜鸟的成长之路(一)
- 分享下多年积累JAVA程序员成长之路
- 分享一下@Override标签背后的小秘密---记录java的思行合一
- 博客,记录程序猿的成长。
- 资深Java程序员分享成长之道
- Android studio NDK成长记录(三)Java调用C的各种情况解析
- Java加密与解密学习记录05-非对称加密算法