Socket安全(二)

news2024/11/28 19:22:10

文章目录

    • 1. 客户端模式
    • 2. 创建安全服务器Socket
    • 3. 配置SSLServerSocket

1. 客户端模式

大多数安全通信中,服务器需要使用适当的证书认证自己。不过客户端不需要(淘宝需要向用户证明它确实是淘宝,但我不需要向淘宝证明我自己的身份)。但这种不对称的行为可能会导致客户端与服务器之间的通信不安全,可能面临中间人攻击、数据泄露以及安全漏洞的利用风险。为了避免类似的问题,可以要求Socket自行认证,这种策略不适用于向一般公众开放的服务。不过,在某些高安全性的内部应用程序中这是合理的。setUserClientMode()方法确定Socket是否需要在第一次握手的时候使用认证。参数为true表示Socket处于客户端模式,因此不会进行自行认证。传入false会进行自行认证。

public abstract void setUseClientMode(boolean mode)throws IllegalArgumentException

这个熟悉对于任何一个Socket都只能设置一次,如果再次设置为抛出IllegalArgumentException,它的相应的get方法可以查看现在这个属性的状态。服务端的安全Socket(即由SSLServerSocket的accept()方法返回的Socket),可以使用setNeedClientAuth()方法,要求与它连接的所有客户端都要进行自行认证(或不认证)。

2. 创建安全服务器Socket

前面介绍的安全的客户端Socket,这里介绍SSL的服务器Socket,它们是javax.net.SSLServerSocket类的实例,由抽象工厂javax.net.SSLServerSocketFactory创建:

public abstract class SSLServerScoektFactory extends ServerSocketFactory

类似于客户端SSLSocketFactorySSLServerScoektFactory的实例也是由getDefault静态方法返回。它同样也有三个重载的creat方法来获得SSLServerSocket的实例:

public abstract ServerSocket createServerSocket(int port) throws IOException
public abstract ServerSocekt createServerSocket(int port, int queueLength) throws IOException
public abstract ServerSocket createServeerSocket(int port, int queueLength, InetAddress interface) throws IOException

创建安全的服务器Socket时,getDefault返回的工厂只支持服务器认证。它并不支持加密。在Sun的参考实现(不同实现流程不同),要由一个com.sun.net.ssl.SSLContext对象负责创建已经充分配置和初始化的安全服务器Socket,必须完成以下步骤:

  1. 使用keytool生成公开密钥和证书
  2. 花钱请可信任的第三方认证你的证书
  3. 为你使用的算法创建一个SSLContext
  4. 为你要使用的证书源创建一个TrustManagerFactory
  5. 为你要使用的密钥类型创建一个KeyManagerFactory
  6. 为密钥和证书数据库创建一个KeyStore对象(Oracle默认的是JKS)
  7. 为密钥和证书填充KeyStore对象。例如使用加密所用的口令短语从文件系统加载
  8. 用KeyStore及其口令短语初始化KeyManagerFactory`
  9. 用KeyManagerFactory中的密钥管理器(必要)、TrustManagerFactory中的信任管理器和一个随机源来初始化上下文(如果愿意接受默认值,后两个可为null)

下面的例子展示了上面的过程:

public class QuizCardBuilder {

    public static void main(String[] args) {
        try {
            //SSLContext 是一个用于创建和管理 SSL/TLS 安全套接字的类。通过SSLContext,你可以配置SSL/TLS的相关参数,如信任管理器、密钥管理器、安全协议等。
            SSLContext context = SSLContext.getInstance("SSL");
            //KeyManagerFactory 是一个用于管理密钥管理器的工厂类。它负责加载密钥材料并生成用于创建 KeyManager 的 KeyManagerFactory 对象。
            //使用 KeyManagerFactory.getInstance("SunX509") 可以获取支持该算法的 KeyManagerFactory 实例。然后,你可以使用该实例来初始化
            // KeyStore 并生成 KeyManager 数组。
            KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
            //KeyStore 是用于存储密钥和证书的类,它提供了一种安全地管理和存储密钥材料的方式。通过 KeyStore,你可以加载、保存和操作密钥和证书。
            KeyStore ks = KeyStore.getInstance("JKS");
            //出于安全考虑,每个密钥库都必须用口令进行加密,在从磁盘加载前必须提供这个口令,口令短语以char[]数组形式存储,所以可以很快地从内存删除,而不是等待垃圾回收
            //用户输入的密码将以字符数组的形式返回,而不是作为字符串,这是为了提高安全性,避免密码在内存中被以明文的形式暴露。
            char[] password = new char[]{'2','0','1','2','1','2','6','8','4','6','a'};
            //通过调用 load() 方法并提供密钥库文件和密码,可以将密钥库文件的内容加载到 ks 这个 KeyStore 对象中,以便后续的密钥和证书的管理和使用
            ks.load(new FileInputStream("/Users/jackchai/Desktop/自学笔记/java项目/leetcode/leetcodetest/out/production/leetcodetest/jnp4e.keys"), password);
            //通过调用 init() 方法并提供 KeyStore 对象和密码,可以初始化 KeyManagerFactory 对象,使其准备好生成 KeyManager 数组,用于后续的 SSL/TLS 通信
            kmf.init(ks, password);
            //通过调用 init() 方法并提供相应的参数,可以初始化 SSLContext 对象,使其准备好进行 SSL/TLS 通信。
            //第一个参数是一个 KeyManager 数组,用于提供与客户端身份验证相关的密钥管理器。
            //第二个参数是一个 TrustManager 数组,用于提供服务器端证书验证相关的信任管理器。在这里,为了简化,将其设置为 null,表示不进行服务器端证书验证
            //第三个参数是一个随机数生成器 SecureRandom 对象,用于产生随机数以供加密操作使用。在这里,将其设置为 null,表示使用默认的随机数生成器
            context.init(kmf.getKeyManagers(), null, null);
            //擦除口令
            Arrays.fill(password, '0');
            //由SSLContext对象创建安全的服务器Socket工厂
            SSLServerSocketFactory factory = context.getServerSocketFactory();
            SSLServerSocket server = (SSLServerSocket) factory.createServerSocket(8080);
            //增加匿名(未认证)密码组
            //获取服务器支持的协议列表
            String[] supported = server.getSupportedProtocols();
            String[] anonCipherSuitesSupported = new String[supported.length];
            int numanonCipherSuitesSupported = 0;
            //遍历支持的协议列表,检查每个协议是否包含"anon"子字符串,如果是,则将该协议添加到匿名加密套件数组中,并将numanonCipherSuitesSupported增加1
            for (int i = 0; i < supported.length; i++) {
                if (supported[i].indexOf("_anon_") > 0) {
                    anonCipherSuitesSupported[numanonCipherSuitesSupported++] = supported[i];
                }
            }
            //获取当前启用的加密套件列表,并创建一个新的加密套件列表newEnabled,长度为旧列表长度加上匿名加密套件的数量。
            // 然后,使用System.arraycopy()方法将旧的加密套件列表和匿名加密套件列表复制到新的加密套件列表中
            String[] oldEnabled = server.getEnabledCipherSuites();
            String[] newEnabled = new String[oldEnabled.length + numanonCipherSuitesSupported];
            System.arraycopy(oldEnabled, 0, newEnabled, 0, oldEnabled.length);
            System.arraycopy(anonCipherSuitesSupported, 0, newEnabled, oldEnabled.length, numanonCipherSuitesSupported);
            server.setEnabledCipherSuites(newEnabled);
            //匿名加密套件(Anonymous Cipher Suites)是一组加密算法和协议,用于在SSL/TLS通信中实现匿名性。通常,SSL/TLS握手过程中,
            // 服务器和客户端都要进行身份验证,以确保通信的安全性和可信性。
            // 然而,匿名加密套件提供了一种匿名通信的选项,其中客户端可以保持匿名状态而不进行身份验证
            //现在所有的设置工作已经完成
            //可以集中进行实际通信了
            while (true) {
                //这个Socket是安全的
                //但从代码中看不出任何现象
                try (Socket theconneciotn = server.accept()) {
                    InputStream in = theconneciotn.getInputStream();
                    int c;
                    while ((c = in.read()) != -1) {
                        System.out.write(c);
                    }
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        } catch (KeyStoreException e) {
            throw new RuntimeException(e);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (CertificateException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (UnrecoverableKeyException | KeyManagementException e) {
            throw new RuntimeException(e);
        }
    }
}

下面使用keytool在控制台生成密钥文件jnp4e.keys

在这里插入图片描述

keytool -genkey -alias ourstore -keystore jnp4e.keys 是一个 keytool 命令,用于生成密钥对并存储到指定的密钥库文件中。逐个参数解释如下:

  • keytool: keytool 是 Java 提供的一个用于管理密钥和证书的工具。
  • genkey: 该选项指示 keytool 生成一个新的密钥对。
  • alias ourstore: -alias 选项指定密钥的别名,这里的别名是 “ourstore”。密钥别名用于在密钥库中唯一标识密钥对。
  • keystore jnp4e.keys: -keystore 选项指定密钥库的文件名,这里的文件名是 “jnp4e.keys”。密钥库是用于存储密钥对和证书的二进制文件。

使用上述命令,keytool 会生成一个新的密钥对,并将其存储在名为 “jnp4e.keys” 的密钥库文件中。生成的密钥对将使用指定的别名 “ourstore” 标识。密钥库文件可以用于后续的加密通信、身份验证或数字签名等操作。

完成后我们可以看到我们的密钥文件

在这里插入图片描述

3. 配置SSLServerSocket

一旦成功地创建并初始化了一个SSLServerSocke它,只使用java.net.ServerSocket继承的方法就可以编写很多应用程序。与SSLSocket类似,SSLServerSocket提供了选择密码组、管理会话和确定客户端是否需要自行认证的方法。

  • 选择密码组

SSLServerSocket类也有3个方法可以确定支持和启用哪些密码组:

public abstract String[] getSupportedCipherSuites()
public abstract String[] getEnableCipherSuites()
public abstract void setEnableCipherSuites(String[] suites)

用法和SSLSocket的密码组类似,都是规定了通信时候的加密算法和协议的规则

  • 会话管理

客户端和服务器必须都同意建立一个会话。服务端使用setEnableSessionCreation()方法指定是否允许会话,另外使用getEnableSessionCreation()方法确定当前是否允许建立会话

public abstract void setEnableSessionCreation(boolean allowSessions)
public abstract boolean getEnableSessionCreation()

默认情况下是允许建立会话的,如果服务器禁止使用会话,需要会话的客户端仍然能够连接。只不过它不会得到一个会话,而必须为每一个Socket再次完成握手。类似的,如果客户端拒绝会话而服务器允许,它们仍然能在没有会话的情况下相互对话。

  • 客户端模式
    SSLServerSocket类有两个方法可以确定和指定是否要求客户端向服务器认证自己,通过向setNeedClientAuth()方法传递true,可以指定只有客户端能够认证自己的连接才会被接受。get方法可以查看这个属性的当前状态。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/590236.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Skywalking9.4.0部署监控项目

1、SkyWalking简介 SkyWalking是国内开源的基于字节码注入的调用链分析以及应用监控分析工具。特点是支持多种插件&#xff0c;UI功能较强&#xff0c;接入端无代码侵入。目前使用厂商最多&#xff0c;版本更新较快&#xff0c;已成为 Apache 基金会顶级项目。 它有哪些功能呢…

WebGPU你让我等的好辛苦啊

什么是WebGPU WebGPU是一种新兴的Web标准&#xff0c;旨在为Web应用程序提供高性能的图形和计算功能。它是一种低级别的图形API&#xff0c;为开发人员提供了对现代GPU的直接访问&#xff0c;以实现更高效的图形渲染和通用计算。 WebGPU的设计目标是提供与现代图形API&#x…

文心一言 VS 讯飞星火 VS chatgpt (26)-- 算法导论5.1 1题

一、证明:假设在过程 HIRE-ASSISTANT 的第 4 行中&#xff0c;我们总能决定哪一个应聘者最佳。则意味着我们知道应聘者排名的全部次序。 文心一言&#xff1a; 证明: 假设在过程 HIRE-ASSISTANT 的第 4 行中&#xff0c;我们总能决定哪一个应聘者最佳。则意味着我们知道应聘…

png图片压缩后黑底问题解决

问题背景 使用thumbnail对图片进行压缩&#xff0c;偶然会发现对png图片出现黑底的情况如下&#xff1a; 压缩前 压缩后 问题解决 对网上搜到的解决方法主要有两种&#xff1a; 1.指定png输出 JAVA - Get black background when uploading PNG image - Stack Overflow 一…

大数据好找工作么?前景如何

大数据好不好找工作不是一概而论的&#xff0c;要根据你个人的学历情况&#xff0c;掌握技能程度&#xff0c;所在城市招聘需求&#xff0c;甚至是你的面试能力和简历是否突出优势有关。 但是毋庸置疑的是&#xff0c;大数据目前的发展前景还是相当优秀的。 我们知道&#xf…

什么是测试开发,聊聊我对测试开发的看法

目录 前 还没来阿里之前&#xff0c;我对测开的看法 多数人眼中的测试开发 来了阿里之后&#xff0c;对测开看法有了转变 阿里的测开是干嘛的 测试平台的好处和不足 我对测试平台的看法 测试平台是测开必需品吗&#xff1f; 实际项目中用不到测试平台&#xff0c;有必要…

GIT | 日常命令查阅表

最近公司代码管控比较乱&#xff0c;有天就利用分支进行了代码梳理&#xff0c;当时就遇到一些困惑&#xff0c;抽空就把git 再学了一下。 以前我是用git命令的&#xff0c;但是敲命令对我来说还是有点麻烦&#xff08;主要是git 功力不够&#xff09;&#xff0c;看到有同事用…

jmeter性能测试技巧(欢迎提问,不定时更新)

问题1 如何在大并发测试下&#xff0c;让登录或者后续接口只执行一次&#xff1f; 分析 2023Jmeter性能测试项目实战教程&#xff0c;十年测试大佬手把手教你做性能&#xff01;_哔哩哔哩_bilibili2023Jmeter性能测试项目实战教程&#xff0c;十年测试大佬手把手教你做性能&…

SQL综合案例之电商漏斗转化分析,pv,uv及

漏斗模型示例&#xff1a; 不同的业务场景有不同的业务路径 : 有先后顺序, 事件可以出现多次 注册转化漏斗 : 启动APP --> APP注册页面--->注册结果 -->提交订单-->支付成功 搜购转化漏斗 : 搜索商品--> 点击商品--->加入购物车-->提交订单-->支付成功…

Scrum中可以有测试人员吗?

作者 | Federico Toledo Scrum 是将质量融入产品开发和创建敏捷团队的宝贵框架。测试人员如何适应这一切&#xff1f;让我们深入研究这篇文章。 毫无疑问&#xff0c;Scrum是在任何环境中为团队寻求业务敏捷性&#xff0c;以及应对不同复杂挑战的最重要工具之一。 正如《福布斯…

在pycharm里安装pytorch环境-GPU版

1、安装Anaconda 在官网下载安装&#xff1a;https://www.anaconda.com/download 2、安装pycharm https://www.jetbrains.com/pycharm/download/#sectionwindows 使用社区版即可。 3、检查conda环境 按winr&#xff0c;输入cmd回车打开命令窗 在命令窗内输入conda 环境无问…

小学课后兴趣班选课平台的设计与实现(ASP.NET,SQLServer)

系统功能模块设计 中小学课后兴趣班选课平台包括前台功能模块和后台功能模块&#xff1a;前台功能模块是给会员使用的功能模块&#xff0c;在前台功能模块中会员可以实现在线注册&#xff0c;登录&#xff0c;查看发布的新闻资讯信息&#xff0c;查看教师&#xff0c;在线留言&…

软件测试的 20 个误区

软件测试中常遇到的 20 个误区&#xff0c;争取能给想从事软件测试的小伙伴一点启发。 1、测试人员不需要了解软件开发知识 抛开自动化测试&#xff0c;测试开发等&#xff0c;这些是必须要学习软件开发知识。功能测试和接口测试等还是需要软件开发知识的&#xff0c;例如新建…

电动汽车、车载充电器及其过流保护电路介绍

摘要&#xff1a;本文通过比亚迪公司的专利了解电动汽车、车载充电器及其过流保护电路&#xff0c;其中&#xff0c;车载充电器包括AC/DC变换器和DC/DC变换器&#xff0c;AC/DC变换器和DC/DC变换器均采用光耦驱动的SiC开关管&#xff0c;过流保护电路包括&#xff1a;电流检测单…

ChatGPT与网络安全

文章目录 一、“AI用于攻击”二、“AI用于安全&#xff08;防御&#xff09;”三、“AI的防御”四、“AI被攻击” ChatGPT作为基于生成式预训练模型&#xff08;GPT&#xff09;的聊天机器人&#xff0c;其核心技术是自然语言处理&#xff08;NLP&#xff09;。随着NLP技术的不…

OS实战笔记(9)-- 构建二级引导器

Grub内核映像格式 Grub工作的时候&#xff0c;需要一个内核映像文件&#xff0c;其中包括了二级引导器模块、内核模块、图片和字库等。这些不同的文件都被放到了一个映像文件中&#xff0c;为了Grub能够正常加载&#xff0c;需要一个预先定义好的格式&#xff0c;以便Grub能解析…

代码实现 ResNet 详解

零、ResNet的介绍 ResNet代码&#xff08;含详细的使用说明&#xff09;&#xff1a; https://github.com/GarsonWw/resnet-garson.git 当谈到深度学习中的卷积神经网络时&#xff0c;ResNet&#xff08;Residual Network&#xff09;是一个备受赞誉且引人注目的架构。ResNet…

最全的mysql编码集问题排查

用navicate导入一个json文件数据的时候&#xff0c;发现中文有一些是乱码的&#xff0c;查了很多资料&#xff0c;发现mysql、navicate编码集都没问题&#xff0c;包括导入流程&#xff0c;那是什么原因呢&#xff1f;想着难道是电脑的编码集影响了&#xff1f;于是调整以后&am…

【C语言】结构体——我就是秩序的创建者!(结构体数组、结构体指针、嵌套、匿名、字面量、伸缩型数组、链式结构)

一、结构体基础1.1 声明和定义1.1 初始化和赋值1.3 访问结构体成员 二、结构体数组2.1 定义和初始化2.2 访问 三、结构体的嵌套五、指向结构体的指针六、向函数传递结构体6.1 只传递结构体成员6.2 传递结构体指针6.3 传递结构体 七、结构体的其他特性——不容小觑7.1 结构体的大…

硬盘数据丢失怎么办?一招轻松恢复硬盘数据!

硬盘应该是最为常用的数据存储设备了&#xff0c;它为电脑等设备提供巨大的存储空间。我们在平时的工作和学习中也经常会使用硬盘来存储数据&#xff0c;很多用户会将多年搜集到的资料存到电脑硬盘里。 硬盘上的文件&#xff0c;不论是工作文档还是照片、视频&#xff0c;对用…