Java安全

引用块内容

概念

加密

加密的过程是把原始数据(明文)转换成第三方无法识别的内容(密文)
加密的目的是保证数据被窃取之后,数据中所包含的信息仍然不会泄露。

解密

解密的过程则是把密文重新转换成明文

加密算法

对称加密算法

使用同一个密钥进行加密和解密
例子:

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/**
 * 使用对称加密方式的双方需要通过可靠的方式来传递密钥。
 * 在示例中是通过文件的方式来传递的 key.dat 。
 * @author Administrator
 *
 */
public class SymmetricEncryption {
    /**
     * 加密方法
     * 1.使用KeyGenerator 生成秘钥,并把密钥编码之后的格式保存下来
     * 2.在得到Cipher类的对象并完成初始化之后,对一段文本进行加密处理,把加密之后的结果数据保存下来。
     * @throws Exception
     */
    public static void encrypt() throws Exception{
        KeyGenerator generator = KeyGenerator.getInstance("DES");
        SecretKey key  = generator.generateKey();
        Files.write(Paths.get("key2.data"), key.getEncoded());
        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        String text = "Hello World";
        byte[]encrypted=cipher.doFinal(text.getBytes());
        Files.write(Paths.get("encrypted2.bin"), encrypted);
    }
    /**
     * 解密方法decrypt中
     * @throws Exception
     */
    public static void decrypt() throws Exception{
        byte[]keyData=Files.readAllBytes(Paths.get("key2.data"));
        SecretKeySpec keySpec = new SecretKeySpec(keyData, "DES");
        Cipher cipher =Cipher.getInstance("DES");
        cipher.init(Cipher.DECRYPT_MODE, keySpec);
        byte[]result=Files.readAllBytes(Paths.get("encrypted2.bin"));
        System.out.println(new String(result));
    }

    public static void main(String[] args) throws Exception {
        encrypt();
        System.out.println("ssssssssss");
        decrypt();
    }
}

非对称加密算法

使用一对密钥分别进行加密和解密,两个密钥分别称为公钥和私钥。使用其中一个密钥进行加密的数据,需要使用另外一个密钥来解密。

公钥

非对称算法的公钥是公开的,需要与程序进行通信的其他代码使用公钥对数据进行加密

私钥

而私钥则由程序妥善保存。程序使用保存的私钥对数据进行解密。

密钥在Java密码框架中有两种表示方式

一种是基于java.security.Key接口的不透明表示方式

另一种是基于java.security.spec.KeySpec接口的透明表示方式。

报文摘要

目的

使用报文摘要的目的是防止数据的内容被恶意篡改。当数据通过网络或其他方式传输时,有可能有第三方对数据进行拦截并篡改其中的内容。数据的接收者会在不知情的情况下使用错误的数据。

原理

报文摘要的做法是使用某种算法对原始数据进行处理,得到一个固定长度的摘要,这个摘要会随着数据一同公开出来。接收者对接收到的数据使用相同的算法计算出摘要,再与正确的摘要进行比较。如果不一致,则说明数据已经被篡改。

特点

  • 摘要算法可以对任意长度的数据进行处理,得到的都是固定长度的摘要。
  • 报文摘要算法具有一个显著的特点,那就是要找到两段内容不同而摘要相同的数据,在计算上几乎是不可能的。这一特点保证如果数据被篡改,总是可以通过摘要的变化来检查出来。
  • 另外,摘要本身也不会暴露原始数据的任何信息。
  • 不过随着技术的进步,一些之前安全的摘要算法,也被发现有安全漏洞。
    示例代码
/**
     * 使用MD5算法计算摘要的示例
     * @throws NoSuchAlgorithmException
     */
    public void useMessageDigest() throws NoSuchAlgorithmException{

        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] digest=md.digest("Hello World".getBytes());
    }

消息验证码(Message Authentication Code, MAC)

与报文摘要的不同在于消息验证码在计算过程中使用了密钥,只有掌握了密钥的接收者才能验证数据的完整性。

特点

消息验证码可以解决摘要本身也可能被篡改的问题。在实现中使用了散列函数的消息验证码被称为HMAC

使用方法

一般的做法是对数据本身使用HMAC计算出消息验证码,再把消息验证码附加在原始数据之后,最后使用密钥对整个数据进行加密之后进行传输。消息验证码使用javax.crypto.Mac类进行计算。

/**
     * 计算消息验证码的示例
     * @throws NoSuchAlgorithmException
     */
    public void useMAC() throws NoSuchAlgorithmException{
        KeyGenerator keyGenerator =KeyGenerator.getInstance("HmacMD5");
        Mac mac = Mac.getInstance("HmacMD5");
        byte[]result =mac.doFinal("Hello World".getBytes());
    }

数字签名

数字签名可以用来实现身份验证功能
在进行数字签名时需要使用一对公钥和私钥。例如,对于进行通信的两个对等体A和B,如果A需要验证B的身份,那么B需要使用私钥对消息进行加密,并把加密结果发送给A,
A使用公钥进行解密。由于私钥只有B知道,当A使用公钥成功对数据进行解密之后,可以判定消息的来源肯定是该公钥对应的持有者B,这就相当于B对消息进行了签名。
数字签名的服务由java.security.Signature类来提供。Signature类的对象有签名和验证两种不同的工作模式。

SSL协议

SSL协议在TCP/IP协议栈中位于传输层协议(TCP)和应用层协议(包括HTTP、Telnet和FTP等)之间。SSL比较常见的使用方式是与HTTP一起使用,用来构建安全的Web应用。SSL协议最早由Netscape公司开发,现在是由IETF组织维护的国际标准。标准化之后的SSL协议改名为传输层安全协议(Transport
Layer Security, TLS)。Java SE 7中默认的实现支持TLS 1.1和TLS 1.2协议。

SSL协议的目:

  • 第一个问题是身份认证,即确保当前正在通信的对等体的身份是合法的。SSL协议允许通信的双方在建立数据连接之前,先进行身份验证。在身份验证中使用经过数字签名的证书。
  • 第二个问题是数据被窃取。SSL协议在传输数据的过程中会对数据进行加密,这样可以保证即便在数据泄露的情况下,其中所包含的信息不会被窃取。
  • 第三个问题是数据可能被篡改。SSL协议对传输的数据添加了消息验证码,接收者可以对数据的完整性进行校验。

在安全套接字连接建立之前,客户端和服务器端之间需要通过握手机制就连接的细节达成一致。当握手结束之后,双方可以按照约定的方式自由发送数据。SSL协议的握手过程比较复杂,大致分成如下几步。

  • 客户端发出连接请求。请求中包含客户端所能支持的SSL协议的最高版本,以及所能使用的加密算法的信息。
  • 服务器端接收到连接请求之后,根据客户端给出的信息,选择双方都能支持的最高版本的SSL协议,并确定双方都能使用的加密算法。服务器端把选择的结果发送给客户端。如果客户端要求认证服务器端的身份,那么服务器端把它所持有的数字证书发送给客户端。如果服务器端也需要认证客户端的身份,那么服务器端向客户端发出认证请求。如果服务器端发送的数字证书中包含的信息不足以在双方之间进行密钥交换,那么服务器端会发送额外的密钥信息。

  • 接着由客户端来处理服务器端返回的响应内容。如果客户端收到了服务器端进行身份验证的请求,那么客户端使用自己的私钥对所持有的数字证书进行加密之后发送给服务器端。客户端生成在数据传输时进行加密操作所使用的密钥,并使用服务器端给出的公钥进行加密之后发送给服务器端。所有这些操作完成之后,客户端发出通知,切换到加密的数据传输方式。

  • 最后由服务器端来完成整个握手过程。如果服务器端在第2)步中选择验证客户端身份,会先验证客户端发送过来的信息是否正确。接着同样切换到加密的数据传输方式。握手过程结束后双方进行数据传输,直到连接关闭。

数字证书

数字证书中包含证书持有者的身份信息和公钥。
在非对称加密算法中,公钥是公开的。使用公钥可以解决如何安全共享密钥的问题。但是还有一个问题是如何确保接收者所得到的公钥来自所声明的真实发送者,而不是伪造的。攻击者可以随意创建一个新的公钥私钥对,并声称该公钥属于另外一个公司或组织。数字证书的目的就是解决这个问题。
证书由用户所信任的机构(Certification Authority)签发,并通过该机构的私钥来加密。数字证书持有者的真实性由信任机构来保证。在有些情况下,某个证书签发机构的真实性需要由另外一个机构的证书来证明。通过这种证明关系形成一个证书的链条,而链条的根是公认的值得信任的机构。只有当证书链条上的所有证书都被信任时,证书中所给出的公钥才能得到信任。支持SSL协议的应用,如浏览器,通常会把一些重要的信任机构的公钥保存起来,在验证时使用。对于一个证书,先使用这些保存的公钥来检验证书本身的合法性。证书检验合法之后,证明其中所包含的身份信息和公钥是真实的,可以使用这个证书中包含的公钥进行身份认证。

在SSL握手过程中的一个重要步骤是双方对数据传输时使用的密钥达成一致。数据传输过程中使用的是对称加密算法。服务器端和客户端持有相同的密钥,客户端把生成的密钥经过服务器端的公钥加密之后,发送给服务器端,服务器端用自己的私钥解密,就得到了双方共同使用的密钥。

HTTPS

HTTPS是一种把HTTP和SSL/TLS协议结合起来的通信方式。在使用HTTPS的情况下,通过HTTP传输的数据都会被加密,保证了数据的安全。

在通过HTTPS方式访问网站时,身份验证变得非常重要。进行身份验证的前提是服务器端可以提供合法有效的证书。网站的提供者通常需要向证书签发机构交纳一定的费用,才能得到有效的证书。在开发中经常会遇到自签发的证书,这些证书是由网站提供者自行创建的。在完整的证书链条中,并没有信任机构签发的证书。当通过HTTPS方式访问使用自签发证书的网站时,浏览器会给出相关的警告信息,要求用户对访问请求进行确认。如果是以程序的方式进行访问的,则访问请求会失败。

不错的博客

阮一峰的三篇文章

数字签名是什么?

http://www.ruanyifeng.com/blog/2011/08/what_is_a_digital_signature.html

图解SSL/TLS协议

http://www.ruanyifeng.com/blog/2014/09/illustration-ssl.html

SSL/TLS协议运行机制的概述

http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html

网站HTTPS 升级指南

http://mp.weixin.qq.com/s/2SYOS1kaDtyOANT9jEPBXQ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值