先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上网络安全知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip204888 (备注网络安全)
正文
/**
* 方法上有DecryptionAnnotation注解的,进入此拦截器
* @param methodParameter 方法参数对象
* @param targetType 参数的类型
* @param converterType 消息转换器
* @return true,进入,false,跳过
*/
@Override
public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
return methodParameter.hasMethodAnnotation(DecryptionAnnotation.class);
}
@Override
public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException {
return inputMessage;
}
/**
* 转换之后,执行此方法,解密,赋值
* @param body spring解析完的参数
* @param inputMessage 输入参数
* @param parameter 参数对象
* @param targetType 参数类型
* @param converterType 消息转换类型
* @return 真实的参数
*/
@SneakyThrows
@Override
public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
// 获取request
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
if (servletRequestAttributes == null) {
throw new ParamException("request错误");
}
HttpServletRequest request = servletRequestAttributes.getRequest();
// 获取数据
ServletInputStream inputStream = request.getInputStream();
RequestData requestData = objectMapper.readValue(inputStream, RequestData.class);
if (requestData == null || StringUtils.isBlank(requestData.getText())) {
throw new ParamException("参数错误");
}
// 获取加密的数据
String text = requestData.getText();
// 放入解密之前的数据
request.setAttribute(CryptoConstant.INPUT_ORIGINAL_DATA, text);
// 解密
String decryptText = null;
try {
decryptText = AESUtil.decrypt(text);
} catch (Exception e) {
throw new ParamException("解密失败");
}
if (StringUtils.isBlank(decryptText)) {
throw new ParamException("解密失败");
}
// 放入解密之后的数据
request.setAttribute(CryptoConstant.INPUT_DECRYPT_DATA, decryptText);
// 获取结果
Object result = objectMapper.readValue(decryptText, body.getClass());
// 强制所有实体类必须继承RequestBase类,设置时间戳
if (result instanceof RequestBase) {
// 获取时间戳
Long currentTimeMillis = ((RequestBase) result).getCurrentTimeMillis();
// 有效期 60秒
long effective = 60*1000;
// 时间差
long expire = System.currentTimeMillis() - currentTimeMillis;
// 是否在有效期内
/*if (Math.abs(expire) > effective) {
throw new ParamException("时间戳不合法");
}*/
// 返回解密之后的数据
return result;
} else {
throw new ParamException(String.format("请求参数类型:%s 未继承:%s", result.getClass().getName(), RequestBase.class.getName()));
}
}
/**
* 如果body为空,转为空对象
* @param body spring解析完的参数
* @param inputMessage 输入参数
* @param parameter 参数对象
* @param targetType 参数类型
* @param converterType 消息转换类型
* @return 真实的参数
*/
@SneakyThrows
@Override
public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
String typeName = targetType.getTypeName();
Class<?> bodyClass = Class.forName(typeName);
return bodyClass.newInstance();
}
}
**2、DecryptionAnnotation.java(解密注解)**
package com.soft.common.annotation;
import java.lang.annotation.*;
/**
- @author Administrator
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DecryptionAnnotation {
}
**3、EncryptResponseBodyAdvice.java(加密切面)**
package com.soft.common.advice;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.soft.common.annotation.EncryptionAnnotation;
import com.soft.common.entity.RequestBase;
import com.soft.common.exception.CryptoException;
import com.soft.common.result.Result;
import com.soft.common.util.AESUtil;
import com.soft.common.util.StringUtils;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.http.ResponseEntity;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
import java.lang.reflect.Type;
@ControllerAdvice
public class EncryptResponseBodyAdvice implements ResponseBodyAdvice<Result<?>> {
@Autowired
private ObjectMapper objectMapper;
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
ParameterizedTypeImpl genericParameterType = (ParameterizedTypeImpl)returnType.getGenericParameterType();
// 如果直接是Result,则返回
if (genericParameterType.getRawType() == Result.class && returnType.hasMethodAnnotation(EncryptionAnnotation.class)) {
return true;
}
if (genericParameterType.getRawType() != ResponseEntity.class) {
return false;
}
// 如果是ResponseEntity<Result>
for (Type type : genericParameterType.getActualTypeArguments()) {
if (((ParameterizedTypeImpl) type).getRawType() == Result.class && returnType.hasMethodAnnotation(EncryptionAnnotation.class)) {
return true;
}
}
return false;
}
@SneakyThrows
@Override
public Result<?> beforeBodyWrite(Result<?> body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
// 加密
Object data = body.getData();
// 如果data为空,直接返回
if (data == null) {
return body;
}
// 如果是实体,并且继承了Request,则放入时间戳
if (data instanceof RequestBase) {
((RequestBase)data).setCurrentTimeMillis(System.currentTimeMillis());
}
String dataText = JSONUtil.toJsonStr(data);
// 如果data为空,直接返回
if (StringUtils.isEmpty(dataText)) {
return body;
}
// 如果位数小于16,报错
if (dataText.length() < 16) {
throw new CryptoException("加密失败,数据小于16位");
}
String encryptText = AESUtil.encryptHex(dataText);
System.out.println("加密后的参数:"+encryptText);
return Result.builder()
.status(body.getStatus())
.data(encryptText)
.message(body.getMessage())
.build();
}
}
**4、EncryptionAnnotation.java(加密注解)**
package com.soft.common.annotation;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EncryptionAnnotation {
}
#### 五、实体类
**1、RequestData.java**
package com.soft.common.entity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@EqualsAndHashCode
public class RequestData implements Serializable{
// 加密的文本
private String text;
}
**2、RequestBase.java**
package com.soft.common.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@EqualsAndHashCode
public class RequestBase {
@TableField(exist = false)
private Long currentTimeMillis;
}
**3、User.java**
package com.soft.entity;
import com.soft.common.entity.RequestBase;
import lombok.Data;
import java.io.Serializable;
/**
- @ClassName User
- @Description
**/
@Data
public class User extends RequestBase implements Serializable {
private Integer id;
private String name;
private String password;
}
#### 六、测试
@Api(tags = “请求方”)
@RestController
@RequestMapping(“/test/request”)
public class TestController implements ResultBuilder {
@PostMapping("/userInfo")
public void get() {
//请求远程接口获取id=2的user(CurrentTimeMillis,对方根据该值判断请求有效期,跟user没有关系)
User user = new User();
user.setId(2);
user.setCurrentTimeMillis(DateUtils.millis(LocalDateTime.now()));
//请求参数加密
String text = AESUtil.encryptHex(JSONObject.toJSONString(user));
//请求参数封装
Map<String,Object> params = new HashMap<>();
params.put("text", text);
//设置请求头
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json;charset=UTF-8");
HttpRequest httpRequest = HttpUtil.createPost("http://x.x.x.x:8088/test/response/getUserInfo");
httpRequest.addHeaders(headers);
httpRequest.body(JSONUtil.toJsonStr(params));
//执行请求
HttpResponse httpResponse = httpRequest.execute();
//返回数据
JSONObject jsonObject = JSON.parseObject(httpResponse.body());
//返回数据解密
String result = AESUtil.decrypt(jsonObject.get("data").toString());
User data = JSONObject.parseObject(result, User.class);
}
}
package com.soft.controller;
@Api(tags = “响应方”)
@RestController
@RequestMapping(“/test/response”)
public class TestController implements ResultBuilder {
/**
* 直接返回对象,不加密
* @param teacher Teacher对象
* @return 不加密的对象
*/
@PostMapping("/get")
public ResponseEntity<Result<?>> get(@Validated @RequestBody Teacher teacher) {
return success(teacher);
}
/**
* 返回加密后的数据
* @param teacher Teacher对象
* @return 返回加密后的数据 ResponseBody<Result>格式
*/
@PostMapping("/encrypt")
@EncryptionAnnotation
public ResponseEntity<Result<?>> encrypt(@Validated @RequestBody Teacher teacher) {
return success(teacher);
}
/**
* 返回加密后的数据
* @param teacher Teacher对象
* @return 返回加密后的数据 Result格式
*/
@PostMapping("/encrypt1")
@EncryptionAnnotation
public Result<?> encrypt1(@Validated @RequestBody Teacher teacher) {
return success(teacher).getBody();
}
/**
* 返回解密后的数据
* @param teacher Teacher对象
* @return 返回解密后的数据
*/
@PostMapping("/decrypt")
@DecryptionAnnotation
public ResponseEntity<Result<?>> decrypt(@Validated @RequestBody Teacher teacher) {
return success(teacher);
}
/**
* 返回加密后的数据
* @EncryptionAnnotation:只对return 的结果加密
* @DecryptionAnnotation:只对请求体的加密参数解密
*/
@PostMapping("/getUserInfo")
@EncryptionAnnotation
@DecryptionAnnotation
public ResponseEntity<Result<?>> getUserInfo(@RequestBody User u ) {
//解密后的参数
System.out.println("解密后的参数:"+u);
//查询数据库
User us = new User();
us.setId(1);
us.setName("aaa");
us.setPassword("aaa111");
//返回加密后的数据
return success(us);
}
}
给大家的福利
零基础入门
对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。
同时每个成长路线对应的板块都有配套的视频提供:
因篇幅有限,仅展示部分资料
网络安全面试题
绿盟护网行动
还有大家最喜欢的黑客技术
网络安全源码合集+工具包
所有资料共282G,朋友们如果有需要全套《网络安全入门+黑客进阶学习资源包》,可以扫描下方二维码领取(如遇扫码问题,可以在评论区留言领取哦)~
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注网络安全)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
全源码合集+工具包**
所有资料共282G,朋友们如果有需要全套《网络安全入门+黑客进阶学习资源包》,可以扫描下方二维码领取(如遇扫码问题,可以在评论区留言领取哦)~
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注网络安全)
[外链图片转存中…(img-x3OsSvAp-1713175874949)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!