对加密解密下面的内容一定要先理解:

甲乙双方要通信,中间的连接可能被人窃听甚至篡改。解决办法就是把传输的内容进行加密,用密文去传输,这样即使被监听也没办法知道信息的具体内容。

加密时,甲乙双方可以约定一个密码A,甲用A加密,乙用A解密,这就是对称加密。对称加密的一个问题是:密钥怎么传递给对方?

貌似没解,于是就出现了非对称加密,非对称加密时有两个密钥,就是公钥也私钥。用公钥加密的只能用私钥解密,反之用私钥加密的则只能用公钥解密。这样在流程上有点儿变化了。

原先在对称加密中,密钥没法传递,现在好了,密钥不用传递,因为公钥是公开的,谁都可以拿到。流程如下:

  1. 甲要给乙发送信息,那么甲需要知道乙的公钥;
  2. 甲用乙的公钥进行加密,将数据传递给乙;
  3. 乙用自己的私钥进行解密,从而获得数据

过程中:

  1. 如果有人窃听到了数据,因为这个人没有乙的私钥,所以没法解密,所以查看不到数据内容;
  2. 如果有人想篡改数据呢?答案也做不到,因为连甲发的什么内容都不知道所以就谈不上篡改了。

这里有点儿要注意的细节是,甲要发送数据时,不是自己造公钥,而是问接收方要公钥。

上述过程中还漏掉了一个问题:虽然篡改不了问题,那我总可以冒名发数据吧?

因为乙的公钥是公开的,那我就可以拿着乙的公钥给乙想发什么就发什么?

乙怎么知道数据甲发过来的呢?答案是用数字签名来验证。

非对称加密RSA就支持数字签名,流程是:

  1. 甲用自己的私钥个数据生成一个签名;
  2. 甲在给乙发送数据的时候,把签名也一并发送过去;
  3. 乙在收到数据的时候,用甲公布的公钥来验证接收到的签名;

总的来说,对应于安全问题的解决办法如下:

  1. 数据完整性问题:数据摘要验证
  2. 数据保密性问题:对称加密&非对称加密
  3. 身份验证问题:数字签名

简单数据转换

Base64

将数据转换为不便于识别的数据算是一种最简单的加密了,比如Base64编码:

public class Base64Util {

    public static void main(String[] args) throws Exception{

        String str = "Hello";
byte[] bytes = str.getBytes();
String encodedStr = encode(bytes);
System.out.println(encodedStr); byte[] decodedBytes = decode(encodedStr);
System.out.println(new String(decodedBytes)); } public static String encode(byte[] bytes){
return new BASE64Encoder().encode(bytes);
} public static byte[] decode(String encodeStr) throws IOException{
return new BASE64Decoder().decodeBuffer(encodeStr);
} }

Java8内置Base64的实现,可以通过java.util.Base64工具类来使用。

输出如下:

SGVsbG8=

Hello

这种编码是可逆的,因此加密的数据越长,则得到的结果越长,因为数据中存储了所有原始数据的细节。另外一些,比如MD5算法,是不可逆的,则属于内容摘要,多长的数据拿过来,最终得到的摘要结果长度都是一样的。因为这个特性所以经常用于校验文件是否被修改过。

数据摘要算法

MD5

public class MD5Util {

    public static void main(String[] args) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
String pwd = "a"; byte[] md5Bytes = md.digest(pwd.getBytes("UTF-8"));
System.out.println(new String(Hex.encode(md5Bytes)));
System.out.println(Base64Util.encode(md5Bytes)); }
}

MD5一般和Base64配合使用,用来加密得到固定长度的Base64码。如果不用Base64编码,Spring的Hex对MD5数据进行了友好的输出。

MD是Message Digest Algorithm的简称,中文名消息摘要算法,目前最新为第五版即MD5,历史版本有MD4、MD2等,由于存在缺陷都已不再使用。消息摘要算法各个版本间的结果是不一样的。

MD2算法产生于1989年;
MD4算法产生于1990年;
MD5算法产生于1991年。

MD5是目前广泛使用的版本,不过其安全性多年前就开始被质疑(碰撞算法)。于是在2008年提出了MD6算法,其后MD6历经数次改进,目前还是试行方案阶段,未被正式使用。

另外,从JDK的API来看,除了MDx家族外,还有其他一些消息摘要算法:

SHA

SHA的全称叫安全散列算法(Secure Hash Algorithm),它是比MD5更安全消息摘要算法。

public class SHAUtil {
public static void main(String[] args) throws Exception{
MessageDigest md = MessageDigest.getInstance("SHA-1");
String str = "Hello";
String str2 = Base64Util.encode(md.digest(str.getBytes()));
System.out.println(str2);
}
}

HMAC

HMAC的全称是哈希消息认证码(Hash Message Authentication Code)。个人觉得,所有的消息摘要无非是要做数据验证。一个重要的例子,我们不会在数据库中保存明文的用户密码,而保存密码的摘要。因为摘要算法是透明的,那么为了防止撞库,就需要在摘要时“加盐”。所加的盐其实也是有讲究的,随机数?当期系统时间?其实都很容易被猜测。HMAC正是来解决这个问题的。它不管具体的消息摘要是怎样的,既可以用MD5也可以用SHA。它关注的是怎样生成这个随机的盐,也就是密钥。在HMAC中,摘要时是需要秘钥的,从而保证了摘要的隐蔽性,因此不容易被撞库。

public class HMACUtil {

    public static void main(String[] args) throws Exception {

        String data = "Hello";
String key = getKey();
System.out.println("key:" + key); String mac = encryptHmac(key.getBytes(), data.getBytes());
System.out.println(mac); System.out.println(encryptHmac(key.getBytes(), "Hello2".getBytes())); } public static String getKey()throws Exception{
KeyGenerator generator = KeyGenerator.getInstance("HmacMD5");
SecretKey key = generator.generateKey();
byte[] bytes = key.getEncoded();
return Base64Util.encode(bytes);
} public static String encryptHmac(byte[] key,byte[] data)throws Exception{
SecretKey secretKey = new SecretKeySpec(key, "HmacMD5");
Mac mac = Mac.getInstance("HmacMD5");
mac.init(secretKey); byte[] resultBytes = mac.doFinal(data);
String resultString = Base64Util.encode(resultBytes);
return resultString;
}
}

HMAC可用的摘要算法名称:

加密解密领域到处都有“秘钥”(Key),索性JDK自己实现了生成很多算法的秘钥的方法(KeyGenerator ),这些算法包括:

其他相关文章:
 
 

参考资料:

http://snowolf.iteye.com/blog/379860

Java加密与解密笔记(一) Base64和数据摘要算法的更多相关文章

  1. Java加密与解密笔记(三) 非对称加密

    非对称的特点是加密和解密时使用的是不同的钥匙.密钥分为公钥和私钥,用公钥加密的数据只能用私钥进行解密,反之亦然. 另外,密钥还可以用于数字签名.数字签名跟上文说的消息摘要是一个道理,通过一定方法对数据 ...

  2. Java加密与解密笔记(四) 高级应用

    术语列表: CA:证书颁发认证机构(Certificate Authority) PEM:隐私增强邮件(Privacy Enhanced Mail),是OpenSSL使用的一种密钥文件. PKI:公钥 ...

  3. Java加密与解密笔记(二) 对称加密

    前面的仅仅是做了编码或者摘要,下面看看真正的加密技术. DES public class DESUtil { static final String ALGORITHM = "DES&quo ...

  4. Java加密技术(一)——BASE64与单向加密算法MD5&SHA&MAC

    Java加密技术(一)——BASE64与单向加密算法MD5&SHA&MAC 博客分类: Java/Security Javabase64macmd5sha     加密解密,曾经是我一 ...

  5. Java加密与解密的艺术 读书心得

    现在项目中加密与解密的方式很多,很早就想整理一下Java中加密与解密的方式,读完<<Java加密与解密的艺术>>一书.借此机会梳理一下这方面的知识点 一.基础普及 安全技术目标 ...

  6. java 加密与解密艺术

    视频来自黑马程序员公开课 对称加密之后的密文可能存在乱码,这些乱码无法识别,信息经过加密后会变成一串毫无规律的二进制串,此时再选择一种编码方式来展示,通常是 BASE64 格式的编码. 为了解决这个问 ...

  7. python接口自动化测试二十七:加密与解密MD5、base64

    # MD5加密 # 由于MD5模块在python3中被移除# 在python3中使用hashlib模块进行md5操作 import hashlib def MD5(str): # 创建md5对象 hl ...

  8. java 加密与解密艺术二

    首先需要明确的是RSA的密钥对不能手动指定,需要通过代码系统生成 接下来我们来介绍下生成密钥对 package com.weiyuan.test; import java.security.KeyPa ...

  9. AES Java加密 C#解密 (128-ECB加密模式)

    在项目中遇到这么一个问题: java端需要把一些数据AES加密后传给C#端,找了好多资料,算是解决了,分享一下: import sun.misc.BASE64Decoder; import sun.m ...

随机推荐

  1. 201521123042《Java程序设计》 第7周学习总结

    1. 本周学习总结 网上看了很多资料,发现这一张图总结的还不错就引用过来了.但是最上面的Map和Collection之间的关系应该是依赖,不是Produces. ①概述:Java集合框架主要包括两种类 ...

  2. 201521123073《Java程序设计》第4周学习总结

    一. 本周学习总结 二. 书面作业 1.注释的应用 2.面向对象设计(大作业1,非常重要) 2.1 将在网上商城购物或者在班级博客进行学习这一过程,描述成一个故事.(不得少于50字,参考QQ群中PPT ...

  3. list,set,map总结

    学习了集合,脑子里list,set,map之间的关系有混乱,在这里整理一下.有兴趣的朋友可以看下. 先看下 list,set,map各自的特点

  4. 201521123037 《Java程序设计》第9周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. java异常继承架构 2. 书面作业 本次PTA作业题集异常 1. 常用异常 题目5-1 1.1 截图你的提交结果( ...

  5. 201521123048 《java程序设计》 第11周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) 1. ...

  6. Hibernate中fetch和lazy介绍

    fetch ,指定关联对象抓取的方式,可以设置fetch = "select" 和 fetch = "join".select方式时先查询返回要查询的主体对象( ...

  7. Java-Filter过滤器用于过滤整个项目的编码

    整个分为实现类以及在web.xml文件中对编写的filter类进行注册 代码如下 package cn.itcast.itcaststore.web.filter; import java.io.IO ...

  8. Linux Ubuntu从零开始部署web环境及项目 -----部署项目 (三)

    上一篇讲了如何在linux搭建web环境,这边将如何部署项目. 1,打包项目包 2,上传项目包 将.war项目包通过xftp上传到tomcat目录wabapps目录下 3,启动项目 通过xshell命 ...

  9. oracle查询用户权限及角色(摘)

    1.查看所有用户: select * from dba_users; select * from all_users; select * from user_users; 2.查看用户或角色系统权限( ...

  10. vector 向量容器用法祥解

    vector(向量): C++中的一种数据结构,确切的说是一个类.它相当于一个动态的数组,当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间的目的. 用法:         ...