java实现RSA加密、解密、签名

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: java实现RSA加密、解密、签名

一、RSA简介


 RSA加密是一种非对称加密。可以在不直接传递密钥的情况下,完成解密。这能够确保信息的安全性,避免了直接传递密钥所造成的被破解的风险。是由一对密钥来进行加解密的过程,分别称为公钥和私钥。两者之间有数学相关,该加密算法的原理就是对一极大整数做因数分解的困难性来保证安全性。通常个人保存私钥,公钥是公开的(可能同时多人持有)。


二、加密和签名的区别


加密和签名都是为 了安全性考虑的,简单的说,加密是为了防止消息泄露,而签名是为了防止消息被篡改。



20190504213734218.png


如上图所示,A系统需要发送信息到B系统,这个过程需要采用RSA非对称加密算法防止信息泄漏和 篡改。首先A、B首先都需要获得各自的一对秘钥(公钥和私钥),然后具体的操作过程如上图文字。


如果我们在实际应用中如果只使用加密和签名中的一种可能带来不同的问题。如果我们在消息传递的过程中只对数据加密不进行签名,这样虽然可保证被截获的消息 不会泄露,但是可以利用截获的公钥,将假信息进行加密,然后传递到B。如果只对信息签名,这样虽然可以防止消息被篡改,但是不能防止消息泄露,所以我们在实际项目中需要根据实际需求进行使用。


总结:公钥加密、私钥解密、私钥签名、公钥验签。

 

三、java代码工具类


3.1 RSA工具类RSAUtil


package com.jack.common.utils;
import java.io.*;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.EncodedKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
/**
 * <p>
 * 由于非对称加密速度极其缓慢,一般文件不使用它来加密而是使用对称加密,<br/>
 * 非对称加密算法可以用来对对称加密的密钥加密,这样保证密钥的安全也就保证了数据的安全
 * </p>
 * 
 */
public class RSAUtil {
  /**
   * 加密算法RSA
   */
  public static final String KEY_ALGORITHM = "RSA";
  private static final int MAX_ENCRYPT_BLOCK = 117;
  private static final int MAX_DECRYPT_BLOCK = 128;
  /**
   * method will close inputSteam
   * 
   * @param pemFileInputStream
   * @return
   */
  public static PublicKey loadPublicKey(InputStream pemFileInputStream) {
    return readPublicKey(readPEMFile(pemFileInputStream));
  }
  /**
   * method will close inputSteam
   * 
   * @param pkcs8PemFileInputStream
   * @return
   */
  public static PrivateKey loadPrivateKey(InputStream pkcs8PemFileInputStream) {
    return readPrivateKey(readPEMFile(pkcs8PemFileInputStream));
  }
  /**
   * 
   * @param pemFile
   * @return
   */
  public static PublicKey loadPublicKey(String pemFile) {
    return readPublicKey(readPEMFile(pemFile));
  }
  /**
   * 
   * @param pkcs8PemFile
   * @return
   */
  public static PrivateKey loadPrivateKey(String pkcs8PemFile) {
    return readPrivateKey(readPEMFile(pkcs8PemFile));
  }
  /**
   * read pem file, delete first and last line, sth. like:<br />
   * <p>
   * -----BEGIN PUBLIC KEY----- -----END PUBLIC KEY-----
   * </p>
   * 
   * @param filename
   * @return
   */
  public static String readPEMFile(String filename) {
    try {
      return readPEMFile(new FileInputStream(filename));
    } catch (FileNotFoundException e) {
      throw new RuntimeException(e);
    }
  }
  /**
   * method will close inputSteam
   * 
   * @param stream
   *            pem file inputstream
   * @return
   */
  public static String readPEMFile(InputStream stream) {
    if (null != stream) {
      BufferedReader in = null;
      StringBuilder ret = new StringBuilder();
      String line;
      try {
        in = new BufferedReader(new InputStreamReader(stream, "ASCII"));
        line = in.readLine();
        while (null != line) {
          if (!(line.startsWith("-----BEGIN ") || line.startsWith("-----END "))) {
            ret.append(line);
            ret.append("\n");
          }
          line = in.readLine();
        }
        return ret.toString();
      } catch (Exception ex) {
        throw new RuntimeException(ex);
      } finally {
        try {
          stream.close();
        } catch (Exception ex) {
          ex.printStackTrace();
        }
        if (null != in) {
          try {
            in.close();
          } catch (Exception ex) {
            ex.printStackTrace();
          }
        }
      }
    }
    return null;
  }
  /**
   * 
   * @param pkcs8Base64String
   *            <p>
   *            delete the first and last line, sth. like below: -----BEGIN
   *            PRIVATE KEY----- -----END PRIVATE KEY-----
   *            </p>
   * @return
   */
  public static PrivateKey readPrivateKey(String pkcs8Base64String) {
    byte[] keyByte = Base64Util.decode(pkcs8Base64String);
    try {
      KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
      EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(keyByte);
      RSAPrivateKey privateKey = (RSAPrivateKey) keyFactory.generatePrivate(privateKeySpec);
      return privateKey;
    } catch (NoSuchAlgorithmException | InvalidKeySpecException ex) {
      throw new RuntimeException(ex);
    }
  }
  public static PublicKey readPublicKey(String pkcs8Base64String) {
    byte[] keyByte = Base64Util.decode(pkcs8Base64String);
    try {
      X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyByte);
      KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
      PublicKey publicKey = (PublicKey) keyFactory.generatePublic(x509KeySpec);
      return publicKey;
    } catch (NoSuchAlgorithmException | InvalidKeySpecException ex) {
      throw new RuntimeException(ex);
    }
  }
  /**
   * <P>
   * 私钥解密
   * </p>
   * 
   * @param encryptedData
   *            已加密数据
   * @param privateKey
   * @return
   */
  public static byte[] decryptByPrivateKey(byte[] encryptedData, PrivateKey privateKey) {
    try {
      KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
      Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
      cipher.init(Cipher.DECRYPT_MODE, privateKey);
      return cipher.doFinal(encryptedData);
    } catch (Exception ex) {
      throw new RuntimeException(ex);
    }
  }
  /**
   * 公钥加密
   * 
   * @param content
   *            待加密内容
   * @param publicKey
   *            公钥
   * @param charset
   *            content的字符集,如UTF-8, GBK, GB2312
   * @return 密文内容 base64 ASCII
   */
  public static String encryptByPublicKey(String content, PublicKey publicKey, String charset) {
    try {
      Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
      cipher.init(Cipher.ENCRYPT_MODE, publicKey);
      byte[] data = (charset == null || charset.isEmpty()) ? content.getBytes() : content.getBytes(charset);
      int inputLen = data.length;
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      int offSet = 0;
      byte[] cache;
      int i = 0;
      // 对数据分段加密
      while (inputLen - offSet > 0) {
        if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
          cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
        } else {
          cache = cipher.doFinal(data, offSet, inputLen - offSet);
        }
        out.write(cache, 0, cache.length);
        i++;
        offSet = i * MAX_ENCRYPT_BLOCK;
      }
      byte[] encryptedData = Base64Util.encode(out.toByteArray());
      out.close();
      return new String(encryptedData, "ASCII");
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
  /**
   * 私钥加密
   * 
   * @param content
   *            待加密内容
   * @param privateKey
   *            私钥
   * @param charset
   *            content的字符集,如UTF-8, GBK, GB2312
   * @return 密文内容 base64 ASCII
   */
  public static String encryptByPrivateKey(String content, PrivateKey privateKey, String charset) {
    try {
      Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
      cipher.init(Cipher.ENCRYPT_MODE, privateKey);
      byte[] data = (charset == null || charset.isEmpty()) ? content.getBytes() : content.getBytes(charset);
      int inputLen = data.length;
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      int offSet = 0;
      byte[] cache;
      int i = 0;
      // 对数据分段加密
      while (inputLen - offSet > 0) {
        if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
          cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
        } else {
          cache = cipher.doFinal(data, offSet, inputLen - offSet);
        }
        out.write(cache, 0, cache.length);
        i++;
        offSet = i * MAX_ENCRYPT_BLOCK;
      }
      byte[] encryptedData = Base64Util.encode(out.toByteArray());
      out.close();
      return new String(encryptedData, "ASCII");
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
  /**
   * 私钥解密
   * 
   * @param content
   *            待解密内容(base64, ASCII)
   * @param privateKey
   *            私钥
   * @param charset
   *            加密前字符的字符集,如UTF-8, GBK, GB2312
   * @return 明文内容
   * @return
   */
  public static String decryptByPrivateKey(String content, PrivateKey privateKey, String charset) {
    try {
      Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
      cipher.init(Cipher.DECRYPT_MODE, privateKey);
      byte[] encryptedData = Base64Util.decode(content);
      int inputLen = encryptedData.length;
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      int offSet = 0;
      byte[] cache;
      int i = 0;
      // 对数据分段解密
      while (inputLen - offSet > 0) {
        if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
          cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
        } else {
          cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
        }
        out.write(cache, 0, cache.length);
        i++;
        offSet = i * MAX_DECRYPT_BLOCK;
      }
      byte[] decryptedData = out.toByteArray();
      out.close();
      return (charset == null || charset.isEmpty()) ? new String(decryptedData)
          : new String(decryptedData, charset);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
  /**
   * 公钥解密
   * 
   * @param content
   *            待解密内容(base64, ASCII)
   * @param publicKey
   *            公钥
   * @param charset
   *            加密前字符的字符集,如UTF-8, GBK, GB2312
   * @return 明文内容
   * @return
   */
  public static String decryptByPublicKey(String content, PublicKey publicKey, String charset) {
    try {
      Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
      cipher.init(Cipher.DECRYPT_MODE, publicKey);
      byte[] encryptedData = Base64Util.decode(content);
      int inputLen = encryptedData.length;
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      int offSet = 0;
      byte[] cache;
      int i = 0;
      // 对数据分段解密
      while (inputLen - offSet > 0) {
        if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
          cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
        } else {
          cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
        }
        out.write(cache, 0, cache.length);
        i++;
        offSet = i * MAX_DECRYPT_BLOCK;
      }
      byte[] decryptedData = out.toByteArray();
      out.close();
      return (charset == null || charset.isEmpty()) ? new String(decryptedData)
          : new String(decryptedData, charset);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
  /**
   * 
   * @param signType 如:SHA1withRSA
   * @param data
   * @param publicKey
   * @param sign base64字符串
   * @return
   * @throws Exception
   */
  public static boolean verifySign(String signType, byte[] data, PublicKey publicKey, String sign) throws Exception {
    Signature signature = Signature.getInstance(signType);
    signature.initVerify(publicKey);
    signature.update(data);
    return signature.verify(Base64Util.decode(sign));
  }
  /**
   * 
   * @param signType 如:SHA1withRSA
   * @param data
   * @param privateKey
   * @return base64字符串
   * @throws Exception
   */
  public static String sign(String signType, byte[] data, PrivateKey privateKey) throws Exception {
        Signature signature = Signature.getInstance(signType);
        signature.initSign(privateKey);
        signature.update(data);
        return new String(Base64Util.encode(signature.sign()));
    }
}

3.2 获得公钥和私钥的工具类ClientUtil

package com.jack.common.utils;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.HashMap;
import java.util.Map;
public class ClientUtil {
    public static final Map<String,String> keyMap = new HashMap<String,String>();
    public static PrivateKey getPrivateKay(String fileTwo){
        String privateKey = keyMap.get("privateKay");
        if(privateKey == null || "".equals(privateKey)){
            privateKey = RSAUtil.readPEMFile(fileTwo);
            keyMap.put("privateKay",privateKey);
        }
        PrivateKey privateKeyTwo = RSAUtil.readPrivateKey(privateKey);
        return privateKeyTwo;
    }
    public static PublicKey getPublicKey(String fileTwo,String orgCode){
        String publicKey = keyMap.get(orgCode);
        if(publicKey == null || "".equals(publicKey)){
            publicKey = RSAUtil.readPEMFile(fileTwo);
            keyMap.put(orgCode,publicKey);
        }
        PublicKey publicKeyTwo = RSAUtil.readPublicKey(publicKey);
        return publicKeyTwo;
    }
}


3.3 添加签名方法

package com.jack.urgerobot.rsa.service;
import com.jack.common.utils.ClientUtil;
import com.jack.common.utils.RSAUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.security.PrivateKey;
import java.security.PublicKey;
@Service
public class SignCommonService {
    private String signType = "SHA1WithRSA";
    public String sign( String content) throws Exception{
        PrivateKey privateKeyTwo = null;
        String fileTwo = this.getClass().getClassLoader().getResource("rsa/UserPri.key").getPath();//我们的私钥文件
        privateKeyTwo = ClientUtil.getPrivateKay(fileTwo);
        String sign = RSAUtil.sign(signType, content.getBytes("utf-8"), privateKeyTwo);
        return sign;
    }
}

注释:秘钥存放位置为项目的resources/rsa/下面


20190505101049244.png


3.4 客户端测试发送数据 加密 签名


package com.jack.urgerobot.rsa.service;
import com.aliyun.oss.common.utils.HttpUtil;
import com.jack.common.utils.ClientUtil;
import com.jack.common.utils.HttpUtils;
import com.jack.common.utils.RSAUtil;
import org.apache.ibatis.javassist.bytecode.stackmap.BasicBlock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.security.PublicKey;
import java.util.HashMap;
/**
 * @author zhenghao
 * @description
 * @date 2019/4/30 11:41
 */
@Service
public class testService {
    @Autowired
    private SignCommonService signCommonService;
    public void testScreit(){
        try {
            String reqData = "{\n" +
                    "\"caseCode\":\""+"12345"+"\",\n" +
                    "\"billNo\":\""+"7687878"+"\",\n" +
                    "}";
            HashMap<String, String> pars = new HashMap<String, String>();
            String fileTwo = this.getClass().getClassLoader().getResource("rsa/userPublic.key").getPath();//客户公钥
            PublicKey publicKeyTwo = ClientUtil.getPublicKey(fileTwo, "mbt");
            String entryContent = RSAUtil.encryptByPublicKey(reqData, publicKeyTwo, "UTF-8");
            pars.put("serviceCode", "mbt");
            pars.put("reqData", entryContent);
            pars.put("sign", signCommonService.sign(reqData));
            HashMap<String,String> headerMap = new HashMap<>();
            headerMap.put("Content-uid", "1");
            headerMap.put("Content-pwkey", "1");
            String r = HttpUtils.postWithHeaders("http://localhost:8090/sign/testSign", headerMap, pars);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3.5 接收端 解密 验签

package com.jack.marketing.rsa.controller;
import com.jack.common.utils.ServletUtils;
import com.jack.marketing.rsa.service.RsaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
/**
 * @author zhenghao
 * @description
 * @date 2019/4/30 16:38
 */
@Controller
@RequestMapping("/sign")
public class RsaController {
    @Autowired
    private RsaService rsaService;
    @RequestMapping("/testSign")
    public void addPartner(HttpServletRequest req, HttpServletResponse res,String orgCode, String sign, String reqData){
        Map map = new HashMap<>();
        map.put("orgCode", orgCode);
        map.put("sign", sign);
        map.put("reqData", reqData);
        String reqJson = rsaService.testSign(orgCode, sign, reqData); //获取传入的签名
        ServletUtils.toJson(reqJson,req,res);
    }
}
package com.jack.marketing.rsa.service;
import com.jack.common.exception.ToUserException;
import com.jack.common.utils.ClientUtil;
import com.jack.common.utils.RSAUtil;
import org.springframework.stereotype.Service;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.HashMap;
/**
 * @author zhenghao
 * @description
 * @date 2019/4/30 15:44
 */
@Service
public class RsaService {
    private static String signType = "SHA1WithRSA";
    private static PrivateKey privateKeyTwo = null;
    private static HashMap<String, PublicKey> publicKeyHashMap = new HashMap<String, PublicKey>();
    public String testSign(String orgCode, String sign, String reqData){
        String reqJson = null;
        System.out.println(orgCode + sign + reqData);
        boolean signOK = false;
        //自己私钥解密
        if (privateKeyTwo == null) {
            String fileTwo = this.getClass().getClassLoader().getResource("rsa/userPri.key").getPath();//我们的私钥文件
            privateKeyTwo = ClientUtil.getPrivateKay(fileTwo);
        }
        reqJson = RSAUtil.decryptByPrivateKey(reqData, privateKeyTwo, "utf-8");
        PublicKey publicKeyTwo = publicKeyHashMap.get(orgCode);
        if (publicKeyTwo == null) {
            try {
                String pubfileTwo = this.getClass().getClassLoader().getResource("rsa/userPublic.key").getPath();//服务方的公钥文件
                publicKeyTwo = ClientUtil.getPublicKey(pubfileTwo, orgCode);
                publicKeyHashMap.put(orgCode, publicKeyTwo);
            } catch (Exception e) {
                throw new ToUserException("上传公钥文件");
            }
        }
        //对方公钥验签
        try {
            signOK = RSAUtil.verifySign(signType, reqJson.getBytes("utf-8"), publicKeyTwo, sign);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (signOK) {
            return reqJson;
        } else {
            throw new ToUserException("验证签名失败");
        }
    }
}

上面的代码已经通过测试,可以直接使用


四 小结


关于RSA的使用,之前在软考的时候了解过,后来在项目中也没有负责写过相关的模块,最近刚好项目中需要调用第三方提供的黑名单查询接口,看了下对方的文档需要使用RSA进行加密和签名,所以查了查相关的资料,将这块的东西写完了,在这总结下,在以后的项目中可以直接使用。

目录
相关文章
|
8天前
|
存储 安全 数据安全/隐私保护
打造安全防线!Python AES&RSA加密工具,黑客绕道走的秘籍
【9月更文挑战第9天】随着数字化时代的到来,信息安全问题日益凸显。本文将介绍如何使用Python结合AES与RSA两种加密算法,构建强大的加密工具。AES以其高效性和强安全性著称,适用于大量数据的快速加密;RSA作为非对称加密算法,在加密小量数据及实现数字签名方面表现卓越。通过整合两者,可以构建既安全又灵活的加密系统。首先,需要安装pycryptodome库。接着,实现AES加密与解密功能,最后利用RSA加密AES密钥,确保其安全传输。这种设计不仅提高了数据传输效率,还增强了密钥交换的安全性,为敏感数据提供坚实保护。
135 43
|
6天前
|
存储 安全 算法
RSA在手,安全我有!Python加密解密技术,让你的数据密码坚不可摧
【9月更文挑战第11天】在数字化时代,信息安全至关重要。传统的加密方法已难以应对日益复杂的网络攻击。RSA加密算法凭借其强大的安全性和广泛的应用场景,成为保护敏感数据的首选。本文介绍RSA的基本原理及在Python中的实现方法,并探讨其优势与挑战。通过使用PyCryptodome库,我们展示了RSA加密解密的完整流程,帮助读者理解如何利用RSA为数据提供安全保障。
19 5
|
7天前
|
安全 算法 数据安全/隐私保护
深度揭秘!Python加密技术的背后,AES与RSA如何守护你的数据安全
【9月更文挑战第10天】随着数字化时代的到来,数据安全成为企业和个人面临的重大挑战。Python 作为功能强大的编程语言,在数据加密领域扮演着重要角色。AES 和 RSA 是两种主流加密算法,分别以对称和非对称加密方式保障数据安全。AES(Advanced Encryption Standard)因其高效性和安全性,在数据加密中广泛应用;而 RSA 则利用公钥和私钥机制,在密钥交换和数字签名方面表现卓越。
21 3
|
6天前
|
存储 安全 数据库
双重防护,无懈可击!Python AES+RSA加密方案,构建最强数据安全堡垒
【9月更文挑战第11天】在数字时代,数据安全至关重要。AES与RSA加密技术相结合,构成了一道坚固防线。AES以其高效性保障数据加密,而RSA则确保密钥安全传输,二者相辅相成,提供双重保护。本文通过Python代码示例展示了这一加密方案的魅力,强调了其在实际应用中的重要性和安全性。使用HTTPS等安全协议传输加密密钥和密文,确保数据在数字世界中自由流通而无忧。
15 1
|
8天前
|
安全 Java 数据安全/隐私保护
- 代码加密混淆工具-Java 编程安全性
在Java编程领域,保护代码安全与知识产权至关重要。本文探讨了代码加密混淆工具的重要性,并介绍了五款流行工具:ProGuard、DexGuard、Jscrambler、DashO 和 Ipa Guard。这些工具通过压缩、优化、混淆和加密等手段,提升代码安全性,保护知识产权。ProGuard 是开源工具,用于压缩和混淆Java代码;DexGuard 专为Android应用程序设计,提供强大加密功能;Jscrambler 基于云,保护Web和移动应用的JavaScript及HTML5代码;DashO 支持多种Java平台和
23 1
|
9天前
|
安全 数据安全/隐私保护 Python
情书也能加密?Python AES&RSA,让每一份数据都充满爱的密码
【9月更文挑战第8天】在这个数字化时代,情书不再局限于纸笔,也可能以电子形式在网络中传递。为了确保其安全,Python提供了AES和RSA等加密工具,为情书编织爱的密码。首先,通过安装pycryptodome库,我们可以利用AES对称加密算法高效保护数据;接着,使用RSA非对称加密算法加密AES密钥和IV,进一步增强安全性。即使情书被截获,没有正确密钥也无法解读内容。让我们用Python为爱情编织一张安全的网,守护每份珍贵情感。
23 2
|
17天前
|
安全 Java 应用服务中间件
网络安全的护城河:漏洞防御与加密技术深入浅出Java并发编程
【8月更文挑战第31天】在数字世界的棋盘上,每一次点击都可能是一步棋。网络安全的战场无声却激烈,漏洞如同裂缝中的风,悄无声息地侵袭着数据的堡垒。本文将揭示网络漏洞的隐蔽角落,探讨如何通过加密技术筑起防线,同时提升个人和组织的安全意识,共同守护我们的数字家园。
|
Java API 数据安全/隐私保护
【小家java】java8新特性之---Base64加密和解密原理
【小家java】java8新特性之---Base64加密和解密原理
|
3天前
|
存储 缓存 安全
【Java面试题汇总】多线程、JUC、锁篇(2023版)
线程和进程的区别、CAS的ABA问题、AQS、哪些地方使用了CAS、怎么保证线程安全、线程同步方式、synchronized的用法及原理、Lock、volatile、线程的六个状态、ThreadLocal、线程通信方式、创建方式、两种创建线程池的方法、线程池设置合适的线程数、线程安全的集合?ConcurrentHashMap、JUC
【Java面试题汇总】多线程、JUC、锁篇(2023版)
|
14天前
|
监控 Java 调度
【Java学习】多线程&JUC万字超详解
本文详细介绍了多线程的概念和三种实现方式,还有一些常见的成员方法,CPU的调动方式,多线程的生命周期,还有线程安全问题,锁和死锁的概念,以及等待唤醒机制,阻塞队列,多线程的六种状态,线程池等
75 6
【Java学习】多线程&JUC万字超详解