https知识了解与javaweb中如何使用https
1) https是什么?
https是一种协议,在说https之前我们先说一下什么是http,http就是我们平时浏览网页时使用的一种协议,https协议传输的数据都是未加密的,也就是明文的,因此使用http协议传输隐私信息非常不安全。为了保证这些隐私数据能够加密传输,王景公司设计了SSL(Secure Socket Layer安全套接字层)协议用于对http协议传输的数据进行加密,从而诞生了https。SSL目前的版本是3.0,被IETF定义在RFC6101中,之后IETF对SSL3.0进行升级,于是出现了TLS(Transport Layer Security)1.0,定义在RFC2246中。实际上我们现在使用的https协议都是TLS协议,但是由于SSL出现的时间比较早,并且依旧被现在的浏览器支持,因此SSL依然是https的代名词,但是无论是TLS还是SSL都是上个世纪的事情,SSL最后一个版本是3.0,今后TLS将会继承SSL优良传统继续为我们进行加密服务。
2) TLS/SSL中使用的几种加密方法,包括非对称加密、对称加密以及HASH算法。
非对称加密算法:
非对称加密算法实现机密信息交换的基本过程是:
甲方生成一对密钥并将其中的一把作为共用密钥向其他方公开;
得到该公用密钥的乙方使用该密钥对机密信息进行加密后再发送给甲方;
甲方再用自己保存的另一把专用密钥对加密后的信息进行解密。
非对称加密算法的保密性比较好,它消除了最终用户交换密钥解密的需要,但加密和解密花费时间长、速度慢,他不适合对文件加密而只适用于对少量数据进行加密。
经典的非对称加密算法如RSA算法等安全性都相当高,非对称加密的典型应用是数字签名。
DH(Diffie-Hellman)
Diffie-Hellman算法(D-H算法),密钥一致协议。是由公开密钥密码体制的奠基人Diffie和Hellman所提出的一种思想。简单的说就是允许两名用户在公开媒体上交换信息以生成"一致"的、可以共享的密钥。换句话说,就是由甲方产出一对密钥(公钥、私钥),乙方依照甲方公钥产生乙方密钥对(公钥、私钥)。以此为基线,作为数据传输保密基础,同时双方使用同一种对称加密算法构建本地密钥(SecretKey)对数据加密。这样,在互通了本地密钥(SecretKey)算法后,甲乙双方公开自己的公钥,使用对方的公钥和刚才产生的私钥加密数据,同时可以使用对方的公钥和自己的私钥对数据解密。不单单是甲乙双方两方,可以扩展为多方共享数据通讯,这样就完成了网络交互数据的安全通讯!该算法源于中国的同余定理——中国馀数定理。
RSA
RSA取名是来自三个开发者的名字。RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的所有密码攻击,已经被ISO推荐为公钥数据加密标准。RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。
EL Gamal
EL Gamal算法是公钥密码体制中的一种,在密码学中占有重要的地位。但是算法所采用的幂剩余计算耗时太多的问题,一直是制约其广泛应用的瓶颈问题。提出一种通过建表,以及对传统二进制算法进行改进,即将指数进行2k进制化,减少原BR算法迭代次数,提高加密解密速度的算法。
ECC
ECC算法以椭圆曲线理论为基础,在创建密钥时可以更快,更小,并且更有效,他是用最大质数的积来产生。
目前Java6提供了DH和RSA两种算法实现,通过Bouncy Castle可以实现Elmal算法支持,另ECC加密算法,目前没有开源组件提供支持。
对称加密算法:
对加密和解密使用相同密钥的加密算法。由于其速度,对称性加密通常在消息发送方需要加密大量数据时使用。对称加密也称为密钥加密。所谓对称,就是采用这种加密方法的双方使用相同的密钥进行加密和解密。
常用的对称加密有:
DES、IDEA、RC2、RC4、SKIPJACK算法等。
为什么讲对称加密本身是不安全的?
下面举个例子来简要说明一下对称加密的工作过程。甲和乙是一对生意搭档,他们住在不同的城市。由于生意上的需要,他们经常会相互之间邮寄重要的货物。为了保证货物的安全,他们商定制作一个保险盒,将物品放入其中。他们打造了两把相同的钥匙分别保管,以便在收到包裹时用这个钥匙打开保险盒,以及在邮寄货物前用这把钥匙锁上保险盒。
上面是一个将重要资源安全传递到目的地的传统方式,只要甲乙小心保管好钥匙,那么就算有人得到保险盒,也无法打开。这个思想被用到了现代计算机通信的信息加密中。在对称加密中,数据发送方将明文(原始数据)和加密密钥一起经过特殊加密算法处理后,使其变成复杂的加密密文发送出去。接收方收到密文后,若想解读原文,则需要使用加密密钥及相同算法的逆算法对密文进行解密,才能使其恢复成可读明文。在对称加密算法中,使用的密钥只有一个,发收信双方都使用这个密钥对数据进行加密和解密。
只要你拿到了这把钥匙,你就可以打开保险盒。
HASH算法:
常用的摘要算法包括MD5、SHA1,SHA256
消息摘要算法的特点:
1) 无论输入的消息有多长,计算出来的消息摘要的长度总是固定的
2) 消息摘要看起来是随机的,看上去是胡乱的凑在一起
3) 只要输入的消息不同,对其进行摘要以后产生的摘要消息也不相同;但相同的输入必会产生相同的输出
4) 消息摘要函数只能进行正向的信息摘要,而无法从摘要中恢复出任何的消息,甚至根本找不到任何与原信息相关的信息。
消息摘要算法的主要特征是加密过程不需要密钥,并且经过加密的数据无法被破解,只有输入相同的明文数据经过相同的消息摘要算法才能得到相同的密文。消息摘要不存在密钥的管理与分发问题,适合分布式网络相同上使用。由于其加密计算的工作量相当客观,所以以前这种算法通常只用于数据量有限的情况下加密,例如计算机口令就是用不可逆算法加密的。
现在好多应用系统的数据库中保存的登录密码采用MD5加密,由于HASH算法的特点是输入相同的消息,最后出来的摘要是固定的特点,所以获得了MD5加密后的密码,我们可以通过暴力破解的方式,与密码库中的密码进行比对,也很容易破解。所以还是要设置的密码复杂点。
3) JavaWeb项目中使用https之后,以前的代码需要修改吗?
这里分几种情况,第一种是你的应用调用外部接口或者系统,那么需要修改这部分的代码。如果你的程序是web项目,并且采用浏览器访问的方式访问系统,那么只需要调整相关的配置就可以了。
我们主要对第二种情况进行说明:
第一步:生成证书文件
可以参考:http://ln-ydc.iteye.com/blog/1335213
第二步:修改web项目中的web.xml文件,增加下面的内容:
<security-constraint>
<web-resource-collection>
<web-resource-name>SSL</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
第三步:修改Tomcat下的conf文件夹中的server.xml文件,把项目端口访问的部分做相应的调整
<Connector port="8443"protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false"keystoreFile="D:/AppServer/Tomcat/apache-tomcat-6.0.32/conf/tomcat.keystore" keystorePass="deleiguo" sslProtocol="TLS" />
注:
keystoreFile:证书文件的位置
方框中的keystore的密码,就是刚才我们设置的“123456”
完成上面的3步,项目就可以采用https访问了。
我们在程序中有的时候使用HttpConnection访问某些链接,如果我们想访问https链接怎么操作呢?
请参考http://www.68idc.cn/help/buildlang/java/20150729465845.html文章。
在上面链接中采用的是JSSE,涉及到了一些类,我们简单把JSSE中涉及到的类说明一下(请参考:http://www.2cto.com/kf/201408/323963.html):
这张图上描述了JSSE中使用的类的结构,下面分别说明一下:
(1) 通信核心类:SSLSoket和SSLServerSocket。对于使用过socket进行通信开发的朋友比较好理解,他们对应就是Socket和ServerSocket,只是表示实现了SSL协议的Socket和ServerSocket,同时他们也是Socket与ServerSocket的子类。SSLSocket负责的事情包括加密套件、管理SSL会话、处理握手结束时间、设置客户端模式或服务器模式。
(2) 客户端与服务器端Socket工厂:SSLSocketFactory和SSLServerSocketFactory。在设计模式中工厂模式是专门用于生产出需要的实例,这里也是把SSLSocket和SSLServerSocket对象创建的工作交给这两个工厂类。
(3) SSL会话:SSLSession。安全通信握手过程需要一个会话,为了提高通信的效率,SSL协议允许多个SSLSocket共享一个SSL会话,在同一个会话中,只有第一个打开的SSLSocket需要进行SSL握手,负责生成密钥及交换密钥,其余的SSLSocket都共享密钥信息。
(4) SSL上下文:SSLContext。它是对整个SSL/TLS协议的封装,为了安全套接字协议的实现,主要负责设置安全通信过程中的各种信息,例如跟证书相关的信息。并且负责构建SSLSocketFactory、SSLServerSocketFactory和SSLEngine等工厂类。
(5) SSL非阻塞引擎:SSLEngine。假如你要进行NIO通信,那么将使用这个类,他让通过过程支持非阻塞的安全通信。
什么是NIO?
传统的Socket IO操作,需要为每个连接创建一个线程,当并发的连接数量非常大的时候,线程占用的栈内存和CPU线程切换的开销将非常巨大。使用NIO,不再需要为每个线程创建单独的线程,可以用一个含有限数量的线程的线程池,甚至一个线程来为任意数量的连接服务。由于线程数量小于连接数量,所以每个线程进行IO操作的时候就不能阻塞,如果阻塞的话,有些连接就得不到处理,NIO提供了这种非阻塞的能力。
详细内容可以参考:http://blog.csdn.net/zhouhl_cn/article/details/6568119
(6) 密钥管理器:KeyManager。此接口负责选择用于证实自己身份的安全证书,发给通信另一方。KeyManager对象由KeyManager工厂类生成。
(7) 信任管理器:TrustManager。此接口负责判断决定是否信任对方的安全证书,TrustManager对象由TrustManagerFactory工厂类生成。
(8) 密钥证书存储设施:KeyStore。这个对象用于存放安全证书,安全证书一般以文件形式存放,KeyStore负责将证书加载到内存。
SSL协议通信中涉及密钥存储的文件格式比较多,容易搞混,下面的图可以简单的描述:
名称 |
作用 |
.cer |
俗称证书,但是这个证书没有私钥,只包含了公钥 |
.pfx |
也称为证书,它一般提供浏览器使用,不仅包含公钥,还包含了私钥,这个私钥是加密的 |
.jks(javakey store) |
密钥存储器,可以同时容纳N个公钥跟私钥,是一个密钥库 |
.keystore |
密钥存储器,跟.jks基本是一样的,不同的公司叫法不一样,默认生成的证书存储库格式 |
.truststore |
信任证书存储库,仅仅包含了通信对方的公钥,你也可以直接把通信对方的jsk作为信任库 |
有的时候,需要把证书(pfx或cer)转化为jsk以便于用Java进行ssl通信,例如一个公司只提供了pfx证书,而我们想用java进行ssl通信时就要把pfx转化为jsk格式。 证书转化可以参考(没有测试):http://blog.csdn.net/a351945755/article/details/23195713 |
我的代码内容:
package com.yimian.test;
import java.io.InputStreamReader;
import java.NET.URL;
import javax.Net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
public class MyX509Test {
public static void main(String[] args) {
try {
goHttps("https://zym:9999/");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void goHttps(String url)throws Exception{
// 创建SSLContext对象,并使用我们指定的信任管理器初始化
TrustManager[] tm = { newMyX509TrustManager() };
SSLContext sslContext =SSLContext.getInstance("SSL","SunJSSE");
sslContext.init(null, tm,newjava.security.SecureRandom());
// 从上述SSLContext对象中得到SSLSocketFactory对象
SSLSocketFactory ssf = sslContext.getSocketFactory();
// 创建URL对象
URL myURL = new URL(url);
// 创建HttpsURLConnection对象,并设置其SSLSocketFactory对象
HttpsURLConnection httpsConn= (HttpsURLConnection) myURL.openConnection();
httpsConn.setSSLSocketFactory(ssf);
// 取得该连接的输入流,以读取响应内容
InputStreamReader insr = newInputStreamReader(httpsConn.getInputStream(),"UTF-8");
// 读取服务器的响应内容并显示
int respInt = insr.read();
while (respInt != -1) {
System.out.print((char) respInt);
respInt = insr.read();
}
}
}
package com.yimian.test;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
/**
* 自定义信任管理器
* https加密
*/
public class MyX509TrustManager implements X509TrustManager{
X509TrustManager sunJSSEX509TrustManager;
private static final String TRUST_MANAGER_ALGORITHM ="SunX509";
private static final String TRUEST_PROVIDER ="SunJSSE";
private static final String CERTS_PWD ="keystore888";
private static final String FILE_PATH ="D:\\tomcat.keystore";
// 构造方法初始化证书信息
MyX509TrustManager() throws Exception{
// 获得keystore实例
KeyStore ks = KeyStore.getInstance("JKS");
// keystore文件流、密码
ks.load(new FileInputStream(FILE_PATH),CERTS_PWD.toCharArray());
// algorithm:加密方式
// provider:提供者
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TRUST_MANAGER_ALGORITHM,TRUEST_PROVIDER);
// 信任管理器初始化证书
tmf.init(ks);
TrustManager[] tms =tmf.getTrustManagers();
for(TrustManager tm:tms){
if (tminstanceofX509TrustManager) {
sunJSSEX509TrustManager = (X509TrustManager) tm;
return;
}
}
// 如果都没有发现,抛出异常
throw new Exception("Couldn'tinitialize!");
}
// 检测客户端是否信任程序
public void checkClientTrusted(X509Certificate[] chain, StringauthType){
try {
sunJSSEX509TrustManager.checkClientTrusted(chain,authType);
} catch (CertificateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 检测服务器端是否信任程序
public void checkServerTrusted(X509Certificate[] chain, StringauthType){
try {
sunJSSEX509TrustManager.checkServerTrusted(chain,authType);
} catch (CertificateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 获得信任的发型证书
public X509Certificate[] getAcceptedIssuers() {
returnsunJSSEX509TrustManager.getAcceptedIssuers();
}
}
https知识了解与javaweb中如何使用https的更多相关文章
- HTTPS相关知识以及在golang中的应用
最近简单学习了HTTPS,并在golang中实践了一下,现在把学到的知识记录下来,方便以后查看,如果有幸能帮到有需要的人就更好了,如果有错误欢迎留言指出. 一些简单的概念,可以自行百度百科 HTTPS ...
- 在JavaWeb中使用Log4j步骤
在JavaWeb中使用Log4J指南.每次在开始写一个项目的时候都忘记Log4J如何配置.所以写个步骤,作为记录. 第一步 下载Log4J jar包 从Apache Logging Services ...
- HTTPS知识小结
HTTPS知识小结 背景1:TCP握手 internet上的两台机器A,B要建立起HTTP连接了,在这之前要先建立TCP连接,情景大概是这样子的: A:你好,我跟你建立一个TCP好吗? B:好啊. A ...
- JavaWeb中监听器+过滤器+拦截器区别、配置和实际应用
JavaWeb中监听器+过滤器+拦截器区别.配置和实际应用 1.前沿上一篇文章提到在web.xml中各个元素的执行顺序是这样的,context-param-->listener-->fil ...
- JavaWeb中文件的上传和下载
JavaWeb中文件的上传和下载 转自: JavaWeb学习总结(五十)——文件上传和下载 - 孤傲苍狼 - 博客园https://www.cnblogs.com/xdp-gacl/p/4200090 ...
- JavaWeb中Cookie会话管理,理解Http无状态处理机制
注:图片如果损坏,点击文章链接:https://www.toutiao.com/i6512995108961387015/ 1.<Servlet简单实现开发部署过程> 2.<Serv ...
- Charles中如何对https抓包
前言:下面介绍关于Charles中如何对https抓包 1.在默认没有相关设置HTTPS需要设置相关操作的时候,会出现下面的情况: 2.下面就是设置SSL Proxying,然后443是默可用的端口 ...
- 在Javaweb中使用Scala
Java 是一门比较优秀的编程语言, 其最大功劳是建立非常繁荣的JVM平台生态.不过 Java 语法比较麻烦,写过 C, Python 的人总是想使用简洁的语法,又希望利用上 Java 平台的强大,因 ...
- 在javaweb中通过servlet类和普通类读取资源文件
javaweb有两种方式读取资源文件 在Servlet中读取,可以使用servletContext,servletContext可以拿到web所有的资源文件,然后随便读,但是这种方法不常用,尽量少在S ...
随机推荐
- 生成学习算法(Generative Learning algorithms)
一.引言 前面我们谈论到的算法都是在给定\(x\)的情况下直接对\(p(y|x;\theta)\)进行建模.例如,逻辑回归利用\(h_\theta(x)=g(\theta^T x)\)对\(p(y|x ...
- Gflags 简明使用
简介 Google 的 gflags 是一套命令行参数处理的开源库.比 getopt 更方便,更功能强大,从 C++的库更好的支持 C++(如 C++的 string 类型).包括 C++的版本和 p ...
- ubuntu 下python环境的切换使用
如何在Anaconda的python和系统自带的python之间切换 一般ubuntu下有三种python环境,1. 系统自带python2,3;在/usr/bin路径下:2. anaconda下安装 ...
- 领扣-1/167 两数之和 Two Sum MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- VS2010如何生成ActiveX控件测试容器
VS2010中默认没有ActiveX控件测试容器TSTCON.exe,而是微软把这个文件放到了例子程序中,需要用户自己编译: 具体方法为: 在VS2010的安装目录中找到以下目录Samples\205 ...
- LDA(latent dirichlet allocation)的应用
http://www.52ml.net/1917.html 主题模型LDA(latent dirichlet allocation)的应用还是很广泛的,之前我自己在检索.图像分类.文本分类.用户评论的 ...
- javascript中addEventListener(attachEvent)具体解释
addEventListener 有三个參数:第一个參数表示事件名称(不含 on,如 "click").第二个參数表示要接收事件处理的函数:第三个參数为 useCapture.样例 ...
- 将iPhone投影到Mac上
将iPhone投影到Mac上 有时候, 出于演示须要, 又或者嫌弃iPhone屏幕太小了, 我想把画面弄到mac上. 这时候, 就须要将iPhone投影到Mac上. 至于怎样做呢? 这就是本文要说明的 ...
- Dubbo-Fail to decode request due to: RpcInvocation
使用Dubbo进行服务化,遇到如下错误: Caused by: com.alibaba.dubbo.remoting.RemotingException: Fail to decode request ...
- 【转】Java四种线程池的使用
Java通过Executors提供四种线程池,分别为:newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程.newFixe ...