Java安全(加密+HTTPS+WEB安全)

news2024/11/15 3:29:45

Java加密

单向加密

接收一段明文,然后以一种不可逆的方式将它转换成一段密文

①、MD5,将无论多长的数据最后编码128位数据,常用文件校验、密码加密、散列数据

byte[] data = ...;//明文数据
MessageDigest md5 = MessageDigest.getInstance("md5");
md5.update(data);//加密后的数据

对明文加密后,拼接一个随机字符串(存储用户密码时可以选择用户信息位salt)
密文=MD5(MD5(明文) + salt)

②、SHA,安全性高于MD5,最终解密结果是160位数据

MessageDigest sha = MessageDigest.getInstance("SHA1");
sha.update(data);

③、HMAC

MAC算法除了HmacMD5,还有HmacSHA1/HmacSHA256/Hmac/Hmac512

//初始化密钥
KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5");
SecretKey secretKey = keyGenerator.generateKey();
byte[] secret = secretKey.getEncoded();

//HMAC加密
SecretKey secretKey = new SecretKeySpec(secret,"HmacMD5");
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
mac.init(secretKey);

byte[] data = ...;//明文
mac.doFinal(data);

对称加密

①、DES

64位的密钥把64位的明文经过16轮替换和移位操作变为64位密文输出块
3个入口参数

  • Key 工作密钥,8个字节64位,史记应用其中的56位
  • Data 要被加密或解密的数据,8个字节64位
  • Mode DES的工作方式,包括加密或解密
//加密
byte[] secret = ...;//密钥
DESKeySpec keySpec = new DESKeySpec(secret);
SecretKey key = SecretKeyFactory.getInstance("DES");
generateSecret(keySpec);

Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE,key);
byte[] encryData = cipher.doFinal(data);//加密数据

//解密
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE,key);
cipher.doFinal(encryData);//解密数据

②、AES

DES的升级版,支持可变分组长度,分组长度可设定为32bit的任意倍数,最小值为128bit,最大值256bit
密钥长度可设定为32bit的任意倍数,范围为128-256bit

byte[] secret = ..;//密钥
SecretKey key = new SecretKeySpec(secret,"AES");

Cipher cipher = Cipher.getInstance(secret,"AES");
cipher.init(Cipher.ENCRYPT_MODE,key);
byte[] encryData = cipher.doFinal(data);//加密数据

Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE,key);
cipher.doFinal(encryData);//解密数据

③、PBE

//生成salt
byte[] salt = new byte[8];
SecureRandom random = new SecureRandom();
random.nextBytes(salt);

//加密
String password = ..;//用户口令
PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWITHMD5andDES");
SecretKey secretKey = keyFactory.generateSecret(keySpec);

PBEParameterSpec paramSpec = new PBEParameterSpec(salt,200);//迭代200次
Cipher cipher = Cipher.getInstance("PBEWITHMD5andDES");
cipher.init(Cipher.ENCRYPT_MODE,secretKey,paramSpec);

byte[] encryData = cipher.doFinal(data);


//解密
PBEParameterSpec paramSpec = new PBEParameterSpec(salt,200);//迭代200次
Cipher cipher = Cipher.getInstance("PBEWITHMD5andDES");
cipher.init(Cipher.DECRYPT_MODE,secretKey,paramSpec);

cipher.doFinal(encryData);

非对称加密

需要两个密钥,一个公开的公钥用来加密数据,一个私有的私钥用来解密数据

RSA

  1. A构建一对密钥,将公钥公布给B,将私钥保留
  2. A使用私钥加密数据并签名,发送给B
  3. B使用A的公钥、签名要验证收到的密文是否有效,若有效则使用A的公钥解密
  4. B使用A的公钥加密数据,发送给A,A使用自己的私钥进行解密
//生成公钥和私钥
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("SA");
keyPairGen.initialize(1024);
KeyPair keyPair = keyPairGen.generateKeyPair();

//公钥
byte[] publicKey = keyPair.getPublic().getencoded();
//私钥
byte[] privateKey = keyPair.getPrivate().getEncoded();

//公钥加密数据
X509EncodedKeySpec x509KeySpec = new X509EncodeKeySpec(publicKeyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
Key publicKey = keyFactory.generatePublic(x509KeySpec);

//对数据加密
Cipher cipher Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE,publicKey);
String plainText = "plain text.";
byte[] encryData = cipher.doFinal(plainText.getBytes());

//私钥解密数据
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");

//对数据解密
Clihper cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE,privateKey);
cipher.doFinal(encryData);

对于私钥使用加密模式,公钥使用解密模式,即可实现私钥签名、公钥验证的流程

DH

  1. A构建一对密钥,将公钥公布给B,将私钥保留
  2. B通过A公钥构架密钥对儿,将公钥公布给A,将私钥保留
  3. AB双方互通本地密钥算法
  4. AB双方公开自己的公钥,使用对方的公钥和刚才产生的私钥加密数据,同时可以使用对方的公钥和自己的私钥对数据解密
//初始化A的公钥和私钥
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DH");
keyPairGenerator.initialize(1024);//密钥字节数
KeyPair keyPair = keyPairGenerator.generateKeyPair();

byte[] aPublicKey = keyPair.getPublic().getEncoded();//Ad的公钥
byte[] aPrivateKey = keyPair.getPrivate().getEncoded();//A的私钥

//初始化B的公钥和私钥
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(aPublicKey);
KeyFactory keyFactory = KeyFactory.getInstance("DH");
PublicKey aPubKey = keyFactory.generatePublic(x509KeySpec);

DHParameterSpec dhParamSpec = ((DHPublicKey) aPubKey).getParams();
//由A的公钥构建B的密钥对
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(keyFactory.getAlgorithm());
keyPairGenerator.ininialize(dhParamSpec);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
byte[] bPublicKey = keyPair.getPublic().getEncoded();//B的公钥
byte[] bPrivateKey = keyPair.getPrivate().getEncoded();//B的私钥

//用A的公钥和B的私钥构建密文
String plainText = "你好";
KeyFactory keyFactory = KeyFactory.getInstance("DH");
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(aPublicKey);
PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(bPrivateKey);
Key priKey = keyFactory.generatePrivate(okcs8KeySpec);

KeyArgeement keyArgee = KeyAgreement.getInstance(keyFactory.getAlgorithm());
keyArgee.init(priKey);
keyAgree.doPhase(pubKey,true);

SecretKey secretKey = keyAgree.generateSecret("DES");//本地密钥
Clipher cipher = Cipher.getInstance(secretKey.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE,secretKey);
byte[] encryData = cipher.doFinal(plainText,getBytes());

//用B的公钥、A的私钥解密
KeyFactory keyFactory = KeyFactory.getInstance("DH");
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(bPublicKey);
PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);

KeyAgreement keyAgree = KeyAgreement.getInstance(keyFactory.getAlgorithm());
keyAgree.init(priKey);
keyAgree.doPhase(pubKey,true);

Secret secretKey = keyAgree.generateSecret("DES");//本地密钥
Clipher cipher = Cipher.getInstance(secretKey.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE,secretKey);

cipher.doFinal(encryData);

HTTPS

不仅对数据进行了加密,还对数据完整性提供了保护,并且提供了身份验证的功能
应用场景:其中一方先生成一个对称加密的密钥,然后通过非对称加密的方式来发送这个密钥,这样双方之后的通信就可以用对称加密这种高效率的算法进行解密了
在这里插入图片描述

Https交互过程:

  1. 客户端向服务端发送请求,将客户端的功能和首选项传递给服务器,包括客户端支持的SSL版本、加密组件列表
  2. 服务器端发送选择的连接参数(从客户端加密组件中筛选出的加密组件内容和压缩方法)以及证书(包含公钥等信息)给客户端
  3. 客户端读取证书中的所有人、有效期等信息并进行校验。然后通过预制的CA验证证书合法性,有问题则提示
  4. 客户端生成用于数据加密的对称密钥,然后用服务器的公钥进行加密并发送给服务器端
  5. 服务器端使用自己的私钥解密数据,获得用于数据加密的对称密钥
  6. 安全的通道建立完毕,后续基于对称呢个加密算法传输数据

在这里插入图片描述

WEB安全

客户端安全:通过浏览器进行攻击的安全问题

  • 跨站点脚本攻击
  • 跨站点请求伪造

服务器端安全问题:通过发送请求到服务器进行攻击的安全问题

  • SQL注入
  • 基于约束条件的SQL攻击
  • DDOS攻击
  • Session fixation

跨站点脚本攻击XSS

  1. 一个Java应用提供一个接口可以上传个人动态,动态内容是富文本
  2. 攻击者上传
  3. 在服务端和客户端程序未做任何过滤的情况下,当其他用户访问这个动态页面就会执行该脚本

防止方式:

  • 对任何允许用户输入的地方做检查,防止其提交脚本相关字符串,如script/onload\onerror等客户端和服务端都要做检查
  • 使用Apache Common-Lang中的StringEscapeUtils的带escape前缀的方法来做转义,过滤掉特殊字符或者替换成HTML转义后的字符
  • 给Cookie属性设置上HttpOnly,可以防止脚本获取Cookie
  • 对输出内容做过滤做过滤,可以在客户端做或者服务端做,服务端主要就是转义HTML字符,客户端可以使用escape方法来过滤

跨站点请求伪造CSRF

  1. 一个用户登录了一个站点,访问https://img-home.csdnimg.cn/images/20230724024159.png?be=1&origin_url=http://xx/delete_notes?id=xx即可删除一个笔记
  2. 一个攻击者在它的站点中构造一个页面,HTML内容
  3. 当用户被有道访问攻击者的站点时就发起了一个删除笔记的请求

防止方式:

  • 对重要请求需要验证码,防止用户不知情的情况下被发送请求
  • 使用类似防盗链的机制,对header的refer进行校验以确认请求来自合法的源
  • 对重要请求都附带一个服务端生成的随机Token,提交时对此Token进行验证。

SQL注入

  1. 服务器端登录验证使用如下方式,其中userName和userPwd都是用户直接上传的参数在这里插入图片描述
  2. 用户提交userName为admin’-,userPwd为字符串xxx(用户自己决定)
  3. 拼接好select * from user where user_name=‘admin’-'and pwd=‘xxx’(–为SQL语句的注释),这样只要存在admin用户,返回的就是admin信息

如果服务器的请求错误没有进一步封装,直接把原始数据错误返回,那么有经验的攻击者通过返回结果多次尝试就能找出SQL注入漏洞
防止方式:

  • 构造sql杜绝拼接用户参数,全部使用PreParedStatement预编译语句,通过?来传递参数
  • 业务层面过滤,转义SQL特殊字符,Apache Commons-Lang中的StringEscapeUtil提供了escapeSQL功能

基于约束条件的SQL攻击

处理SQL中的字符串时,字符串末尾的空格字符都会被删除,包括WHERE子句和INSERT子句,但LIKE子句除外
在任意的INSERT查询中,SQL会根据varchar(n)来限制字符串最大长度,超过n个字符串的字符只保留前n个字符
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

防止方式:

  • 为具有唯一性的那些列添加UNIQUE索引
  • 在数据库操作前先将输入参数修剪为特定长度

分布式拒绝服务攻击DDOS攻击

攻击者利用多台机器同时向某个服务发送大量请求,人为构造并发压力,冲垮服务器

  • SYN flood
  • UDP flood
  • ICMP flood

SYN flood利用了TCP连续三次握手先发送SYN机制,通过发送大量的SYN包使得服务器建立大量半连接消耗资源

解决方式:

  • 合理使用缓存、异步提高应用性能
  • 合理使用云计算相关组件,自动识别高峰流量并自动扩容
  • 应用限制某一IP频繁的请求,黑名单。通过redis中incr和expire实现
String ip NetworkUtil.getClientIP(request,false);//获取客户端IP地址
String key = "ddos." + ip;
long count = suishenRedisTemplate.incr(key);
if(count >1000){
	throw new AccessException("access too frequently with id:" + StringUtils.defaultString(ip));
}else{
	if(count == 1){
		suishenRedisTemplate.expire(key,10);
	}
	return true;
}

上述代码即可将同一IP的请求限制在10秒10000次
此逻辑越靠近链路前面效果越好,比如直接在NGINX中拦截,比业务中更好

会话固定Session fixation

基于Session做用户会话管理,浏览器中Session Id存储在Cookie中,甚至直接附带在query参数中
如果Session在未登录的情况下不发生改变的话,Session fixation就形成了。

  1. 攻击者进入网站http://xxx.com
  2. 攻击者发送http://xx.com?JESSIONID=123456给一个用户
  3. 用户单击此链接进入网站,由于URL后面带有JESSIONID,因此直接作为Session的id
  4. 用户成功登录后,攻击者就可以利用伪造的Session ID获取用户的各种操作权限

攻击的关键点就是Tomcat使用了JSESSIONID作为SessionID
因此防范核心之一就是不能使用客户端传来的SessionID

  • 不要接受由GET或者POST参数指定的Session ID值
  • 针对每一个请求都生成新的Session
  • 只接受服务器端生成的Session ID
  • 为Session指定过期时间

Java Web项目可以通过实现一个拦截器,将使用query参数传递JESSIONID的请求的Session删除

public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)throws IOException,ServletException{
	if(httpRequest.isRequestedSessionIdFromURL()){
		HttpSession session = httpRequest.getSession();
		if(session != null){
			session.invalidate();
		}
	}
}

此外,每一次登录后的Session都重新生成ID,并设置合理的失效期

public JSONResult login(@RequestBody LoginRequestBody requestBody,ServletRequest request){
	boolean loginResult = doLogin();
	if(loginResult){
		request.changeSessionId();//重新生成SessionID
		request.getSession().setMaxInactiveInterval(1800);//30分钟失效
	}
}

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

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

相关文章

大数据新视界 --大数据大厂之Kubernetes与大数据:容器化部署的最佳实践

💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

【软件资料集】系统培训方案(Word项目参考2024)

1. 培训概述 2. 培训目的 3. 培训对象及要求 3.1. 培训对象 3.2. 培训人员基本要求 4. 培训方式 5. 培训内容 6. 培训讲师 7. 培训教材 8. 培训质量保证 8.1. 用户培训确认报告 8.2. 培训疑问解答 获取方式:本文末个人名片直接获取。 软件资料清单列表部分文档清单&…

opencv实战项目二十四:棋盘格相机内参标定

文章目录 前言一、简介:二、使用步骤2.1制作标定板2.2 拍摄不同角度的标定板2.3计算棋盘格角点并优化2.4计算相机参数 三、整体代码实现: 前言 在数字图像处理和计算机视觉领域,相机标定是一个至关重要的步骤。它为相机提供了一个准确的数学…

Tomcat 乱码问题彻底解决

1. 终端乱码问题 找到 tomcat 安装目录下的 conf ---> logging.properties .修改ConsoleHandler.endcoding GBK (如果在idea中设置了UTF-8字符集,这里就不需要修改) 2. CMD命令窗口设置编码 参考:WIN10的cmd查看编码方式&am…

Nature|PathChat:病理学多模态生成性AI助手的创新与应用|顶刊精析·24-09-21

小罗碎碎念 今日顶刊:Nature 这篇文章今年6月就发表了,当时我分析的时候,还是预印本,没有排版。今天第一篇推文介绍的是Faisal Mahmood ,所以又把这篇文章拉出来详细分析一下。 作者角色作者姓名单位名称单位英文名称第…

PMP--二模--解题--61-70

文章目录 4.整合管理61、 [单选] 为解决具有挑战性的客户请求,启动了一个项目。该项目必须在短时间内交付。项目经理应该怎么做来尽可能提高项目的成功率? 14.敏捷--MVP--最小可行产品--使用最小可行产品获得客户尽早地反馈。完整性和交付是主观的。团队…

构建高可用和高防御力的云服务架构第二部分:SLB负载均衡(2/5)

在现代云服务中,负载均衡(Load Balancing)是一种关键技术,用于优化资源利用、最小化响应时间、提高系统的可伸缩性和可靠性。负载均衡器位于客户端和服务器之间,根据预设的策略将请求分发到多个服务器上,以…

华为HarmonyOS地图服务 4 - 通过“地图相机“控制地图的可见区域

场景介绍 华为地图的移动是通过模拟相机移动的方式实现的,您可以通过改变相机位置,来控制地图的可见区域,效果如图所示。 本章节将向您介绍相机的各个属性与含义,并移动相机。 相机移动前 接口…

基于lnmp搭建wordpress

一、案例目标 (1)了解LNMP环境的组成。 (2)了解LNMP环境的部署与安装。 (2)了解WordPress应用的部署与使用。 二、节点规划 IP 主机名 节点 192.168.200.20 lnmp lnmp服务节点 三、案例实施 LN…

基于微信小程序的购物系统+php(lw+演示+源码+运行)

基于微信小程序的购物系统 摘要 随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了基于微信小程序的购物系统的开发全过程。通过分析基于微信小程序的购物系统管理的不足,创建了一个计算机管理基于微信小…

1.Spring-容器-注册

一、Bean和获取Bean (1)创建IoC容器: SpringApplication.run(类名.class, args); ConfigurableApplicationContext ioc SpringApplication.run(Spring01IocApplication.class, args); (2)将对象注册到IoC容器中&am…

[Vue] 从零开始使用 Vite 创建 Vue 项目

📚 一、安装 Node.js Node.js 是一个运行 JavaScript 代码的 JavaScript 运行时,它允许我们在服务器端运行 JavaScript 代码。以下是安装 Node.js 的步骤: 🌐 访问 Node.js 国内网站:https://nodejs.cn/ &#x1f4…

【如何在 Windows 10 主机上通过 VMware 安装 Windows 11 虚拟机,并共享主机网络】

环境说明 主机操作系统:Windows 10虚拟机操作系统:Windows 11虚拟机软件:VMware 步骤一:确保主机(Windows 10)网络连接正常 启动网络加速软件:在主机上启动软件,确保主机可以正常访…

基于LSTM的温度时序预测

1.背景 本文接【时序预测SARIMAX模型】 一文,采用LSTM模型进行平均温度数据预测。具体的背景和数据分析就不做重复说明,感兴趣可以去看上文即可。 2.LSTM模型 RNN(Recurrent Neural Network,循环神经网络)是一种特殊…

AI驱动TDSQL-C Serverless 数据库技术实战营-ai学生选课系统数据分析

以前用过腾讯的TDSQL-MYSQL,TBASE,最近了解到TDSQL-C serverless,本次试验结合的AI大模型驱动来学习实战TDSQL-C serverless,体验服务化的数据库,和一句简单描述进行学生选课系统数据分析; 我使用的分析数据…

C++初阶-list用法总结

目录 1.迭代器的分类 2.算法举例 3.push_back/emplace_back 4.insert/erase函数介绍 5.splice函数介绍 5.1用法一:把一个链表里面的数据给另外一个链表 5.2 用法二:调整链表当前的节点数据 6.unique去重函数介绍 1.迭代器的分类 我们的这个迭代器…

【alluxio编译报错】Some files do not have the expected license header

Some files do not have the expected license header 快捷导航 在开始解决问题之前,大家可以通过下面的导航快速找到相关资源啦!💡👇 快捷导航链接地址备注相关文档-ambaribigtop自定义组件集成https://blog.csdn.net/TTBIGDA…

【Elasticsearch系列十八】Ik 分词器

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

通信入门系列书籍推荐一:通信原理和通信原理学习辅导

微信公众号上线,搜索公众号小灰灰的FPGA,关注可获取相关源码,定期更新有关FPGA的项目以及开源项目源码,包括但不限于各类检测芯片驱动、低速接口驱动、高速接口驱动、数据信号处理、图像处理以及AXI总线等 本节目录 一、背景 二、通信原理 …

石岩体育馆附近的免费停车场探寻

坐标:石岩体育馆侧的石清大道断头路, 如果运气好的话,遇到刚好有车开出的话,我觉得可以作为中长期的免费停车点 第一次路过的时候,把我震惊了,我一直以为石岩停车位紧张比市区还严重,因为石岩大部分为统建楼…