面试实战 问题三十四 对称加密 和 非对称加密 spring 拦截器 spring 过滤器

对称加密 和 非对称加密

对称加密

  • 原理:对称加密是一种加密方法,使用相同的密钥进行加密和解密数据。加密过程是通过特定的加密算法,将明文数据按照密钥规则转换为密文;解密过程则是使用相同的密钥将密文还原为明文。这种加密方法快速高效,适用于加密大量数据,但密钥的安全分发和存储至关重要,因为一旦密钥泄露,加密的数据就可能被轻易解密。
  • 应用:常用于对大量数据的加密,如文件加密、数据库加密等。例如在需要对数据库中的敏感信息进行加密存储时,可使用对称加密算法对数据进行加密,提高数据的安全性。
  • Java 加密项目中的使用:在 Java 中,常见的对称加密算法有 AES、DES 等。以下是一个 Java 实现 AES 对称加密的示例代码:
java 复制代码
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class AESEncryptionExample {

    public static String encrypt(String plainText, SecretKey secretKey) throws Exception {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    public static String decrypt(String encryptedText, SecretKey secretKey) throws Exception {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] decodedBytes = Base64.getDecoder().decode(encryptedText);
        byte[] decryptedBytes = cipher.doFinal(decodedBytes);
        return new String(decryptedBytes, StandardCharsets.UTF_8);
    }

    public static void main(String[] args) throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        keyGenerator.init(128);
        SecretKey secretKey = keyGenerator.generateKey();

        String plainText = "Hello, Java Encryption!";
        String encryptedText = encrypt(plainText, secretKey);
        String decryptedText = decrypt(encryptedText, secretKey);

        System.out.println("Plain Text: " + plainText);
        System.out.println("Encrypted Text: " + encryptedText);
        System.out.println("Decrypted Text: " + decryptedText);
    }
}

非对称加密

  • 原理:非对称加密算法需要一对密钥,即一把私钥和一把公钥。公钥用于加密数据,私钥用于解密数据或进行数字签名。数据使用公钥加密后,只有对应的私钥才能解密;私钥进行签名后,公钥可以验证签名的真实性。非对称加密可以避免对称加密算法中密钥传输安全性的问题,但加解密速度较慢。
  • 应用:常用于数字签名、密钥协商、身份验证等方面。例如在数字证书中,使用非对称加密算法进行签名,确保证书的真实性和完整性;在 SSL/TLS 协议中,使用非对称加密算法进行密钥协商,生成对称加密的密钥。
  • Java 加密项目中的使用:在 Java 中,常见的非对称加密算法有 RSA、ECC 等。以下是一个 Java 实现 RSA 非对称加密的示例代码:
java 复制代码
import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.Base64;

public class RSAEncryptionExample {

    public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048);
        return keyPairGenerator.generateKeyPair();
    }

    public static String encrypt(String plainText, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    public static String decrypt(String encryptedText, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decodedBytes = Base64.getDecoder().decode(encryptedText);
        byte[] decryptedBytes = cipher.doFinal(decodedBytes);
        return new String(decryptedBytes, StandardCharsets.UTF_8);
    }

    public static void main(String[] args) throws Exception {
        KeyPair keyPair = generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();

        String plainText = "Hello, Java Encryption!";
        String encryptedText = encrypt(plainText, publicKey);
        String decryptedText = decrypt(encryptedText, privateKey);

        System.out.println("Plain Text: " + plainText);
        System.out.println("Encrypted Text: " + encryptedText);
        System.out.println("Decrypted Text: " + decryptedText);
    }
}

spring 拦截器

使用方法

在 Spring 开发中使用拦截器,通常需要以下几个步骤。首先,创建一个实现 HandlerInterceptor 接口的拦截器类,该接口有三个方法:preHandle(在请求处理之前调用)、postHandle(在请求处理之后,视图渲染之前调用)和 afterCompletion(在整个请求完成之后调用)。以下是一个简单的拦截器示例:

java 复制代码
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CustomInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 在请求处理之前执行的逻辑
        System.out.println("Pre-handle method is called");
        return true; // 返回 true 表示继续执行请求处理流程
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, org.springframework.web.servlet.ModelAndView modelAndView) throws Exception {
        // 在请求处理之后,视图渲染之前执行的逻辑
        System.out.println("Post-handle method is called");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 在整个请求完成之后执行的逻辑
        System.out.println("After-completion method is called");
    }
}

然后,需要将这个拦截器注册到 Spring 配置中。可以通过继承 WebMvcConfigurerAdapter(Spring Boot 2.0 之前)或实现 WebMvcConfigurer(Spring Boot 2.0 及之后)来完成注册:

java 复制代码
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new CustomInterceptor())
               .addPathPatterns("/**"); // 拦截所有请求
    }
}

原理

Spring 拦截器是基于 Java 的反射机制和 Spring 的 AOP(面向切面编程)思想实现的。在 Spring MVC 中,DispatcherServlet 是核心控制器,它负责接收客户端请求并将请求分发给相应的处理器。当请求到达 DispatcherServlet 后,DispatcherServlet 会根据请求的 URL 找到对应的处理器映射器,然后通过处理器映射器找到处理该请求的处理器(通常是一个控制器方法)。在执行处理器之前,DispatcherServlet 会调用拦截器的 preHandle 方法,如果 preHandle 方法返回 true,则继续执行处理器;如果返回 false,则请求处理流程终止。在处理器执行完成后,DispatcherServlet 会调用拦截器的 postHandle 方法,最后在整个请求完成后调用 afterCompletion 方法。

应用场景

Spring 拦截器在企业级应用中有广泛的应用场景。例如,权限校验方面,在 preHandle 方法中可以检查用户是否具有访问某个资源的权限,如果没有权限,则可以直接返回错误信息,阻止请求继续处理;日志记录方面,可以在 preHandle 方法中记录请求的相关信息,如请求的 URL、请求参数等,在 afterCompletion 方法中记录请求的处理结果和执行时间;性能监控方面,可以在 preHandle 方法中记录请求开始时间,在 afterCompletion 方法中计算请求的执行时间,从而监控系统的性能。

spring 过滤器

介绍

Spring 过滤器是 Java Web 应用中的一种组件,它放在 web 资源之前,可以在请求抵达它所应用的 web 资源(可以是一个 Servlet、一个 Jsp 页面,甚至是一个 HTML 页面)之前截获进入的请求,并且在它返回到客户之前截获输出请求。其目的是重用代码,处于客户端与被请求资源之间,可对请求和响应进行预处理和后处理。

使用方法

以下是一个简单的 Spring 过滤器使用示例:

java 复制代码
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

// 使用 @WebFilter 注解来定义过滤器
@WebFilter(filterName = "customFilter", urlPatterns = "/*")
public class CustomFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化方法,在过滤器启动时调用
        System.out.println("CustomFilter initialized");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 在请求处理之前执行的逻辑
        System.out.println("Pre-processing request in CustomFilter");

        // 调用 FilterChain 的 doFilter 方法,将请求传递给下一个过滤器或目标资源
        chain.doFilter(request, response);

        // 在请求处理之后执行的逻辑
        System.out.println("Post-processing request in CustomFilter");
    }

    @Override
    public void destroy() {
        // 销毁方法,在过滤器销毁时调用
        System.out.println("CustomFilter destroyed");
    }
}

要使这个过滤器生效,还需要在 Spring Boot 主类上添加 @ServletComponentScan 注解:

java 复制代码
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

@SpringBootApplication
@ServletComponentScan
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

原理

Spring 过滤器基于 Java 的 Servlet 规范实现。当客户端发送请求时,请求首先会到达过滤器。过滤器接收到请求和响应对象后,可以对它们进行预处理,例如修改请求参数、设置响应头信息等。在过滤器中,通过 FilterChain 对象的 doFilter 方法将请求传递给下一个过滤器或目标资源。如果还有其他过滤器,则继续执行下一个过滤器的 doFilter 方法;如果没有其他过滤器,则请求会到达目标资源(如 Servlet 或 JSP)。目标资源处理完请求后,响应会沿着过滤器链反向返回,此时过滤器可以对响应进行后处理,例如修改响应内容、记录日志等。

相关推荐
xqqxqxxq2 小时前
Java 集合框架之线性表(List)实现技术笔记
java·笔记·python
L0CK2 小时前
RESTful风格解析
java
程序员小假2 小时前
我们来说说 ThreadLocal 的原理,使用场景及内存泄漏问题
java·后端
何中应2 小时前
LinkedHashMap使用
java·后端·缓存
tryxr2 小时前
Java 多线程标志位的使用
java·开发语言·volatile·内存可见性·标志位
talenteddriver2 小时前
java: Java8以后hashmap扩容后根据高位确定元素新位置
java·算法·哈希算法
云泽8082 小时前
STL容器性能探秘:stack、queue、deque的实现与CPU缓存命中率优化
java·c++·缓存
yyy(十一月限定版)3 小时前
c语言——栈和队列
java·开发语言·数据结构
本地运行没问题3 小时前
基于Java注解、反射与动态代理:打造简易ORM框架
java