HTTPS中的证书、SSL证书、X509证书 初探 讲解

HTTPS中的证书初探

简介

证书是什么?我们为什么需要证书呢?HTTPS中的证书是干什么的?带着这些疑问我们讲了解一下证书。

​ 现在互联网时代,各个终端都在相互通讯中,每秒都会有亿万的信息被传递着。但是这些交互的信息有的十分重要,如果不加保护,这就有可能导致被截获甚至篡改,导致了不可期望的事情出现。举一个简单例子,当我们用手机银行转账的时候,请求银行的服务器,发送转账相关请求消息金额账户什么 的。如果传递给银行的服务器的消息被截获篡改且不被发现这就便十分危险,如果把金额和目标账户修改后,我们就会受到损失财产。我们先详细的阐述一下我们在通讯的过程会受到什么样的攻击。怎么面对危机是我们将要解决的主要任务

通讯中的杀手:中间人攻击(Man-in-the-middle attack)

​ 我们和别人通讯的时候 肯定不希望有任何人来打扰我们或者是恶意修改我们传递的信息,这就是要防止中间人攻击。我们上面举得那个转账的例子就是 属于中间人攻击的一个例子。

什么是中间人攻击呢?

​ 我们一般通讯的时候需要的是两端,好比服务器和客户端。攻击者在这两端中间,传递转发消息。在这个过程中会查看我们的消息甚至做出 修改,来危害我们的通讯安全。我们现在尝试突破中间人的攻击。

我们使用图示演示一下中间人攻击,本来AB之间通讯的挺好的,忽然来了一个攻击者C,潜入到了他俩通讯的中间,进行信息的拦截和转发。

在这里插入图片描述

在这里插入图片描述

​ 攻击C的潜入让我们的通讯变得无比不安全,首先我们通讯内容全被他看到,而且有可能修改我们传递的信息,我们还发现不了这就很危险了,就像上面我们那个转账的例子。

​ 攻击c的主要任务是和A通讯的时候模拟B,和B通讯的时候模拟A。是A和B都无法真正的发现。我首先想到解决方案就是加密,我们怎么加密呢?

​ 如果我们使用对称密钥进行加密,如果A把要加密的密钥发送给B,然后双方使用加密。但是这明显不行,密钥同样会被劫持到,甚至给你替换掉。

​ 那我们使用公钥加密的呢(公钥加密文章),双发都发给对方 公钥,然后对方就是用公钥加密,收到消息用自己的私钥进行解密。

在这里插入图片描述

邪恶的攻击者C呢,就会把自己模拟称成对方想要通讯的一方,把自己的公钥传递给对方,保存发送方的密钥。比如A想把自己的公钥pub_key_a发送给了B,结果攻击者C在中间替换成自己的pub_key_c了,并记下pub_key_a。B像发送的自己的公钥pulic_key_b,C也会做同样的操作。

​ 这样AB都会用pulic_key_c进行加密,攻击者C当然会使用对应的私钥进行解密这些信息,并作出修改,然后使用pub_key_a加密发送给A或者使用 pub_key_b加密发送给B,这样的话AB双方都不会发现他们信息被拦截修改了。

​ 很明显使用公钥加密无法防止中间人的攻击,对于使用公钥加密算法去协商密钥的做法,也会像上面一样,攻击者C模拟通讯双方的行为,来达到中间人攻击的效果。

​ 我们怎么防止中间人攻击呢?这里面有一个很明显的点,就是如果我们知道这个公钥是来自于理想的对方这一切都就会解决。怎么保证我们接收的公钥来自理想的对方呢?那就是证书

怎么保证通讯安全:数字证书

​ https中的使用SSL或者是TLS协议来保证通讯安全,防止中间人攻击的。SSL或者TLS协议就是使用的X509证书来保证公钥的是来自期望的一方。https就是保证 http安全通讯的,它其实就是在http和tcp之间增加一层协议来保证通讯的安全。
在这里插入图片描述

​ 我们先了解一下证书的样子,证书里面的信息有公钥和签名等相关信息。如果我们想把自己公钥交给对方使用,现在都是把含有自己公钥的证书发送给对方,对方会检验证书是否是信任证书。

​ 证书里面是什么样子呢?证书又是怎么保证安全的呢?

证书的核心部分是一把公钥和签名还有一些信息(公钥用途、过期时间、签发者信息、拥有者信息、废弃列表等等)
在这里插入图片描述

​ 证书里面的签名就是使用某一个权威的私钥(权威机构拥有,去签发可以被大家信任的证书)对公钥和其他信息进行签名,怎么验证证书的是可信的没有被修改的呢?当我们通讯的时候拿到对面传递来的证书的时候,假设我们有一把可信任的公钥(也是权威私钥对应的权威公钥),去进行验证签名,如果验证通过就保证这个证书可信且没有被修改的,是我信任的权威私钥签发的,这就是使用的是签名的不可修改性和不可抵赖的特性。

在这里插入图片描述

​ 现在问题就来了,我怎么拿到这个可信任的权威公钥呢?其实这个公钥也是在证书里面的。这个证书就是我们已知的信任证书,一般这些证书的公钥都是用来签发其他证书的,就上面上面证书的生成一样。证书的签发都是有一些专业的权威机构进行签发,再把他们签发证书相关的公钥用证书的形式公布出来。像我们浏览器啊,系统啊就会内置一些权威机构的证书,当然我们也可以手动添加我们所信任的证书,证书所包含的公钥可验证权威机构所签发的证书。

在这里插入图片描述
在这里插入图片描述

如果我们想要拥有其他人可以信任证书,我们就得去权威机构提供相关信息签发证书。

​ 在权威机构内部也不是 只能有一个证书去签发用户来申请的证书,他们会有一些不同部门,不同部门处理不同的证书签发。这些部门都会有一个可以签发的证书。每一个部门的证书都是由权威机构里面的一个核心证书签发,这样就会形成一个树状结构,这个证书就是根部证书,那么根部证书又是谁签发的呢?根部证书是有自己签发的,没错,和他下一层的证书使用相同的私钥签发,这种自我签发的证书称之为自签证书

在这里插入图片描述

​ 最终的叶子证书我们将会颁发给证书的申请者使用 ,当我们在使用这些由专业的权威机构的签发证书时候,我也必须拿到这些中间证书,形成一个证书链,因为在认证的过程中,只要信任这个根部证书,通过传递验证的方式我们最终就能验证我们使用的叶子证书(也可认为是终端证书)可不可信,如下图。

在这里插入图片描述

我们使用Https的安全通讯协议传递证书的时候也是发送给对方一个证书链,对方通过根部证书就能校验最终的叶子证书可不可信。
在这里插入图片描述

我们抓TLS协议的包再证明一下。

在这里插入图片描述

​ 其实我们光有证书还是不够的,还需要有专门的安全协议像TLS协议,来使用我们的证书进行握手协商,来写出一个或者几个密钥。进而保证我们通讯的安全。

总结

​ 今天我们明白了通讯过程中我们将会面对各种各样的攻击,其中最令人深恶痛疾的是中间人攻击,中间人攻击,通过模拟通讯双方的行为,来达到对通讯信息的修改,还让通讯双方不能发现。这种攻击将会造成很大损失。

​ 我们在解决的时候发现公钥加密算法,可以不用传递要可以解密的私钥就能达到加密的效果,但是传递公钥的时候 依然可能被攻击者模拟通讯双方,依然是不安全的。

​ 证书的出现解决了公钥来自可信任的对方,这就需要我们有一个可信任的签发证书的机构,进行签发。签发机构有很多部门可以签发证书,不同部门有不同的签发职能,这些部门的证书是由他们自己内部的根证书来签发的。

​ 这将会形成证书链,我们在校验的时候使用是根部证书去校验,在TLS协议中是传递的就是证书链。这样我们就可以只信任某个签发机构的根部证书,就可以认证这个机构所有签发的证书。

​ 下面一篇文章我们将会深入的了解X509证书,在面对 一些其他的问题时,证书是怎么就解决的?比如证书失效,证书的校验等。

在这里插入图片描述

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java是一种流行的面向对象编程语言,可以用于开发各种类型的应用程序,包括Web应用程序。HTTPS是一种用于Web应用程序的安全协议,它使用SSL/TLS加密通信以保护数据的安全传输。SSL证书HTTPS协议的重要组成部分,它用于验证Web服务器的身份,防止间人攻击。 然而,有时开发人员需要绕过SSL证书,这种情况通常发生在开发、测试或调试阶段。在Java,可以使用以下代码绕过SSL证书: ``` TrustManager[] trustManagerArray = new TrustManager[] { new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] certs, String authType) { } public void checkServerTrusted(X509Certificate[] certs, String authType) { } } }; SSLContext sslContext = SSLContext.getInstance("SSL"); sslContext.init(null, trustManagerArray, new SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); ``` 以上代码,我们创建了一个TrustManager数组,并使用X509TrustManager的实现类来实现 getAcceptedIssuers()、checkClientTrusted()和checkServerTrusted()方法。在checkServerTrusted()方法,我们不进行任何检查,这样就可以绕过SSL证书。 然后,我们使用SSLContext来创建一个默认的SSLSocketFactory对象,并调用setDefaultSSLSocketFactory()方法将其设置为默认的SSLSocketFactory。这样,我们就可以绕过SSL证书,使用不受信任的证书建立安全连接。 需要注意的是,绕过SSL证书不是安全的做法,只能在开发和测试过程使用。在生产环境,必须使用受信任的SSL证书来保护数据的安全传输。 ### 回答2: Java是一种流行的编程语言,其提供了许多操作网络的工具和函数库。其HTTPS是一种安全HTTP协议,可以使用SSL证书来验证身份和保护数据传输。但有时候,我们需要绕过SSL证书以访问某些网站或服务。本文将介绍如何在Java实现绕过SSL证书的方法。 在Java,我们可以使用JSSE(Java Secure Socket Extension)库来操作SSL协议。JSSE提供了TrustManager和HostnameVerifier两个接口,用于验证SSL证书和主机名。我们可以自定义这两个接口的实现,以达到绕过SSL证书的目的。 下面给出两种实现方式: 1. 自定义TrustManager TrustManager是验证服务器证书的接口。我们可以自定义一个TrustManager的实现,使之信任所有证书。代码如下: ``` TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] certs, String authType) { } public void checkServerTrusted(X509Certificate[] certs, String authType) { } } }; SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); ``` 上述代码,我们自定义了一个TrustManager,并将它加入到SSLContext。然后,我们将默认的SSLSocketFactory替换成了我们自定义的sslContext的SocketFactory。 2. 自定义HostnameVerifier HostnameVerifier用于验证主机名。我们可以自定义一个HostnameVerifier的实现,使之信任所有主机名。代码如下: ``` HostnameVerifier allHostsValid = new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }; HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid); ``` 上述代码,我们自定义一个HostnameVerifier,并将其设置为默认的HostnameVerifier。 通过以上两种方式,我们可以绕过SSL证书,但这样做可能会造成安全隐患。因此,我们应该谨慎使用,尽可能避免绕过SSL证书。 ### 回答3: SSL证书是一种安全证书,用于对互联网上的信息进行加密和验证身份。Java是一种计算机编程语言,通常用于开发Web应用程序和网络服务。在访问HTTPS网站时,Java会默认检查SSL证书是否有效,如果证书无效,则会阻止访问。不过,有时候我们需要绕过SSL证书,这种情况通常出现在安全测试或调试过程。 有多种方法可以绕过Java的SSL证书检查,其最常见的方法是使用自定义信任管理器。Java的信任管理器用于验证远程服务器的标识,从而决定是否信任该服务器。我们可以自定义一个信任管理器来绕过证书检查。以下是实现步骤: 1.实现自定义的X509TrustManager。这个类继承java.security.cert.X509Certificate,并重写checkClientTrusted()和checkServerTrusted()方法。这两个方法用于验证客户端和服务器的身份,我们可以在这里实现绕过证书验证并输出日志。 2.创建SSLContext对象。SSLContext是用于建立SSL连接的协议对象,我们需要创建一个支持我们自定义的信任管理器的SSLContext对象。使用默认协议,可以通过以下代码实现: ``` SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, new TrustManager[] { new MyTrustManager() }, new java.security.SecureRandom()); ``` 3.创建HttpsURLConnection对象。HttpURLConnection是用于发送HTTP请求的Java类,HttpsURLConnection则是Https协议的连接对象,我们需要使用HttpsURLConnection对象来发送HTTPS请求。 ``` URL url = new URL("https://www.example.com"); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); ``` 4.设置SSLContext和HostnameVerifier。将我们自定义的SSLContext和一个实现了HostnameVerifier接口的对象(用于验证域名)设置到连接对象。 ``` conn.setSSLSocketFactory(sc.getSocketFactory()); conn.setHostnameVerifier((hostname, session) -> true); ``` 5.执行请求并读取响应。发送请求并读取响应,此时将自动检测SSL证书并绕过验证。 ``` InputStream in = conn.getInputStream(); // do something with input stream ``` 需要注意的是,绕过SSL证书验证可能会导致安全风险,不应在生产环境使用。在测试和调试时,务必小心谨慎,并注意保护您的机密信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值