頁面登錄數據的加密(前端+后端)

本加密過程使用的 AES+RSA

概要

1.使用AES對傳輸數據進行加密

AES為對稱加密,加密和解決所需要的key是一樣的,所以攔截到AES key就可以直接解密,所以需要結果RSA進行加密

2.對AES的key進行RSA加密

RSA為非對稱加密,客戶端只能獲取到publicKey(公鑰),而解密只能使用服務器的privateKey(私鑰)進行解密,從而保證傳輸過程的安全性

代碼解析

前端代碼

<!DOCTYPE html>
<html>
<head><meta name="viewport" content="width=device-width"/><title>Login</title><script src="./jquery-3.7.1.min.js"></script><script src="./jsencrypt.min.js"></script><script src="./crypto-js.min.js"></script><script type="text/javascript">$(function () {// 設置公鑰(通常從服務器獲取)const publicKey ="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA25Da8op9FPY/wfVk2gnB\nzzT6RPF95+l1tjLG9Z9+jMvFh3JA4C888fuCGN57E3qwdZcNGNZhQoEbve/tCPTw\nn9mbIu62O9/uY6nsACymSHeLahJYlNOVf4YBTsxQ7t2KQr8J8A7i88+cE+9SFdf7\n3Qg+8Wj3BJk0haPA9PUQFm+D/124gfr/j4oTJ5G+OMKwXPhv6Y5j0IOTys1oEItB\nAr79BbK/B0q3cFT6tYQxoRCM8XVLoERmI/V4lX8Vyof9cfPkK+8UGcMKMD59jvXT\nEVNmwtkoWzb8Pcu7GW1pcrSfw9+9hMDgy5j771V0KxmEqklJB7ct6mUgd+x0UsUa\nHwIDAQAB";// 用RSA加密AES密鑰const encryptor = new JSEncrypt();encryptor.setPublicKey(publicKey);const key = "abcdef0123456789"; // 16位密鑰,測試成功后可改為隨機生成16位的字符串const iv =  "0123456789abcdef";  // 16位初始向量,測試成功后可改為隨機生成16位的字符串const data = "需要加密的數據";const utf8Key = CryptoJS.enc.Utf8.parse(key);const utf8Iv = CryptoJS.enc.Utf8.parse(iv);//AES加密的數據作為傳輸的參數const encrypted = CryptoJS.AES.encrypt(data, utf8Key, {iv: utf8Iv,mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.Pkcs7});const object = new Object();object.password = encrypted.toString();//RAS加密的key作為參數進行傳輸object.aesKey = encryptor.encrypt(key);object.iv = iv.toString();console.log(JSON.stringify(object));});</script>
</head>
<body>
<div><input type="text" id="data" value=""/>
</div>
</body>
</html>

后端代碼 :?

package rsaaes;import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;
import java.util.Map;@Slf4j
@RestController
public class LoginController {@AutowiredRsaKeyPair rsaKeyPair;@GetMapping("/getPublicKey")public Map<String, String> getPublicKey() {Map<String, String> ajax = new HashMap<>();ajax.put("publicKey", rsaKeyPair.getPublicKey());return ajax;}@PostMapping("/login")public Map<String, String> login(@RequestBody LoginBody loginBody) {Map<String, String> ajax = new HashMap<>();String password = obtainPassword(loginBody);ajax.put("token", "token自己生成");return ajax;}private String obtainPassword(LoginBody loginBody) {if (StringUtils.isBlank(loginBody.getAesKey())) {return loginBody.getPassword();}return obtainDecryptedPwd(loginBody);}private String obtainDecryptedPwd(LoginBody loginBody) {// 解密AES密鑰String aesKey = RSAUtils.decryptPem(rsaKeyPair.getPrivateKey(), loginBody.getAesKey());String decryptedPwd = AESDecryptor.decrypt(loginBody.getPassword(), aesKey, loginBody.getIv());return decryptedPwd;}}
package rsaaes;/*** @Description TODO* @Author chengcheng* @Date 2025/7/2 14:32*/
public class RsaKeyPair {private String publicKey;private String privateKey;public RsaKeyPair(String publicKey, String privateKey) {this.publicKey = publicKey;this.privateKey = privateKey;}public String getPublicKey() {return publicKey;}public void setPublicKey(String publicKey) {this.publicKey = publicKey;}public String getPrivateKey() {return privateKey;}public void setPrivateKey(String privateKey) {this.privateKey = privateKey;}
}
package rsaaes;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;@Configuration
public class SecurityConfig1 {@Beanpublic KeyPairGenerator keyPairGenerator() throws Exception {KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");generator.initialize(2048); // 2048位密鑰return generator;}@Beanpublic RsaKeyPair rsaKeyPair(KeyPairGenerator generator) {KeyPair keyPair = generator.generateKeyPair();// 獲取公鑰和私鑰的Base64編碼字符串String publicKey = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded());String privateKey = Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded());String publicKeyPem = publicKey.replaceAll("(.{64})", "$1\n");String privateKeyPem = privateKey.replaceAll("(.{64})", "$1\n");return new RsaKeyPair(publicKeyPem,privateKeyPem);}public static void main(String[] args) {try {KeyPairGenerator generator = null;generator = KeyPairGenerator.getInstance("RSA");generator.initialize(2048); // 2048位密鑰KeyPair keyPair = generator.generateKeyPair();System.out.println("getPrivate---" + keyPair.getPrivate());System.out.println("getPublic---" + keyPair.getPublic());} catch (NoSuchAlgorithmException e) {throw new RuntimeException(e);}}}
package rsaaes;import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;public class AESDecryptor {public static String decrypt(String encryptedData, String key, String iv) {try {// Base64解碼byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData);// 創建密鑰和初始向量SecretKeySpec secretKey = new SecretKeySpec(key.getBytes("UTF-8"), "AES");IvParameterSpec ivParameter = new IvParameterSpec(iv.getBytes("UTF-8"));// 初始化CipherCipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameter);// 解密byte[] decryptedBytes = cipher.doFinal(encryptedBytes);return new String(decryptedBytes, "UTF-8");} catch (Exception e) {e.printStackTrace();return null;}}public static void main(String[] args) {String key = "abcdef0123456789";String iv = "0123456789abcdef";String encryptedData = "c3Go0Em03BUc7ytkKRg9rpPc8QLm8wUPrAmfUOJ/ANI=";String decryptedText = decrypt(encryptedData, key, iv);System.out.println("解密結果: " + decryptedText);}
}
package rsaaes;import lombok.Data;/*** @Description TODO* @Author chengcheng* @Date 2025/7/2 15:11*/
@Data
public class LoginBody {public String aesKey;public String iv;private String username;private String password;private String code;private String uuid;
}
package rsaaes;import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import javax.crypto.Cipher;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidParameterException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;/*** RSA算法加密/解密工具類*/
@Slf4j
public class RSAUtils {private static final Logger LOGGER = LoggerFactory.getLogger(RSAUtils.class);/** 算法名稱 */private static final String ALGORITHM = "RSA";/** 默認密鑰大小 */private static final int KEY_SIZE = 1024;/** 用來指定保存密鑰對的文件名和存儲的名稱 */private static final String PUBLIC_KEY_NAME = "publicKey";private static final String PRIVATE_KEY_NAME = "privateKey";private static final String PUBLIC_FILENAME = "publicKey.properties";private static final String PRIVATE_FILENAME = "privateKey.properties";/** 密鑰對生成器 */private static KeyPairGenerator keyPairGenerator = null;private static KeyFactory keyFactory = null;/** 緩存的密鑰對 */private static KeyPair keyPair = null;/** Base64 編碼/解碼器 JDK1.8 */private static Base64.Decoder decoder = Base64.getDecoder();private static Base64.Encoder encoder = Base64.getEncoder();/** 初始化密鑰工廠 */static {try {keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);keyFactory = KeyFactory.getInstance(ALGORITHM);} catch (NoSuchAlgorithmException e) {LOGGER.error(e.getMessage(), e);}}/** 私有構造器 */private RSAUtils() {}/*** 生成密鑰對* 將密鑰分別用Base64編碼保存到#publicKey.properties#和#privateKey.properties#文件中* 保存的默認名稱分別為publicKey和privateKey*/public static synchronized Map<String, String> generateKeyPair() {try {keyPairGenerator.initialize(KEY_SIZE, new SecureRandom(UUID.randomUUID().toString().replaceAll("-", "").getBytes()));keyPair = keyPairGenerator.generateKeyPair();} catch (InvalidParameterException e) {LOGGER.error("KeyPairGenerator does not support a key length of " + KEY_SIZE + ".", e);} catch (NullPointerException e) {LOGGER.error("RSAUtils#key_pair_gen is null,can not generate KeyPairGenerator instance.", e);}RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();String publicKeyString = encoder.encodeToString(rsaPublicKey.getEncoded());String privateKeyString = encoder.encodeToString(rsaPrivateKey.getEncoded());storeKey(publicKeyString, PUBLIC_KEY_NAME, PUBLIC_FILENAME);storeKey(privateKeyString, PRIVATE_KEY_NAME, PRIVATE_FILENAME);Map<String, String> keyPair = new HashMap<>();keyPair.put("publicKey", publicKeyString);keyPair.put("privateKey", privateKeyString);return keyPair;}/*** 將指定的密鑰字符串保存到文件中,如果找不到文件,就創建* @param keyString 密鑰的Base64編碼字符串(值)* @param keyName  保存在文件中的名稱(鍵)* @param fileName 目標文件名*/private static void storeKey(String keyString, String keyName, String fileName) {Properties properties = new Properties();//存放密鑰的絕對地址String path = null;try {path = RSAUtils.class.getClassLoader().getResource(fileName).toString();path = path.substring(path.indexOf(":") + 1);} catch (NullPointerException e) {//如果不存#fileName#就創建LOGGER.warn("storeKey()# " + fileName + " is not exist.Begin to create this file.");String classPath = RSAUtils.class.getClassLoader().getResource("").toString();String prefix = classPath.substring(classPath.indexOf(":") + 1);String suffix = fileName;File file = new File(prefix + suffix);try {file.createNewFile();path = file.getAbsolutePath();} catch (IOException e1) {LOGGER.error(fileName + " create fail.", e1);}}try (OutputStream out = new FileOutputStream(path)) {properties.setProperty(keyName, keyString);properties.store(out, "There is " + keyName);} catch (FileNotFoundException e) {LOGGER.error("ModulusAndExponent.properties is not found.", e);} catch (IOException e) {LOGGER.error("OutputStream output failed.", e);}}/*** 獲取密鑰字符串* @param keyName 需要獲取的密鑰名* @param fileName 密鑰所在文件* @return Base64編碼的密鑰字符串*/private static String getKeyString(String keyName, String fileName) {if (RSAUtils.class.getClassLoader().getResource(fileName) == null) {LOGGER.warn("getKeyString()# " + fileName + " is not exist.Will run #generateKeyPair()# firstly.");generateKeyPair();}try (InputStream in = RSAUtils.class.getClassLoader().getResource(fileName).openStream()) {Properties properties = new Properties();properties.load(in);return properties.getProperty(keyName);} catch (IOException e) {LOGGER.error("getKeyString()#" + e.getMessage(), e);}return null;}/*** 從文件獲取RSA公鑰* @return RSA公鑰* @throws InvalidKeySpecException*/public static RSAPublicKey getPublicKey() {try {byte[] keyBytes = decoder.decode(getKeyString(PUBLIC_KEY_NAME, PUBLIC_FILENAME));X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);return (RSAPublicKey) keyFactory.generatePublic(x509EncodedKeySpec);} catch (InvalidKeySpecException e) {LOGGER.error("getPublicKey()#" + e.getMessage(), e);}return null;}/*** 從文件獲取RSA私鑰* @return RSA私鑰* @throws InvalidKeySpecException*/public static RSAPrivateKey getPrivateKey() {try {byte[] keyBytes = decoder.decode(getKeyString(PRIVATE_KEY_NAME, PRIVATE_FILENAME));PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);return (RSAPrivateKey) keyFactory.generatePrivate(pkcs8EncodedKeySpec);} catch (InvalidKeySpecException e) {LOGGER.error("getPrivateKey()#" + e.getMessage(), e);}return null;}/*** RSA公鑰加密* @param content 等待加密的數據* @param publicKey RSA 公鑰 if null then getPublicKey()* @return 加密后的密文(16進制的字符串)*/public static String encryptByPublic(byte[] content, PublicKey publicKey) {if (publicKey == null) {publicKey = getPublicKey();}try {Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, publicKey);//該密鑰能夠加密的最大字節長度int splitLength = ((RSAPublicKey) publicKey).getModulus().bitLength() / 8 - 11;byte[][] arrays = splitBytes(content, splitLength);StringBuffer stringBuffer = new StringBuffer();for (byte[] array : arrays) {stringBuffer.append(bytesToHexString(cipher.doFinal(array)));}return stringBuffer.toString();} catch (Exception e) {LOGGER.error("encrypt()#NoSuchAlgorithmException", e);}return null;}/*** RSA私鑰加密* @param content 等待加密的數據* @param privateKey RSA 私鑰 if null then getPrivateKey()* @return 加密后的密文(16進制的字符串)*/public static String encryptByPrivate(byte[] content, PrivateKey privateKey) {if (privateKey == null) {privateKey = getPrivateKey();}try {Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, privateKey);//該密鑰能夠加密的最大字節長度int splitLength = ((RSAPrivateKey) privateKey).getModulus().bitLength() / 8 - 11;byte[][] arrays = splitBytes(content, splitLength);StringBuffer stringBuffer = new StringBuffer();for (byte[] array : arrays) {stringBuffer.append(bytesToHexString(cipher.doFinal(array)));}return stringBuffer.toString();} catch (Exception e) {LOGGER.error("encrypt()#NoSuchAlgorithmException", e);}return null;}/*** RSA私鑰解密* @param content 等待解密的數據* @param privateKey RSA 私鑰 if null then getPrivateKey()* @return 解密后的明文*/public static String decryptByPrivate(String content, PrivateKey privateKey) {if (privateKey == null) {privateKey = getPrivateKey();}try {Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, privateKey);//該密鑰能夠加密的最大字節長度int splitLength = ((RSAPrivateKey) privateKey).getModulus().bitLength() / 8;byte[] contentBytes = hexStringToBytes(content);byte[][] arrays = splitBytes(contentBytes, splitLength);StringBuffer stringBuffer = new StringBuffer();String sTemp = null;for (byte[] array : arrays) {stringBuffer.append(new String(cipher.doFinal(array)));}return stringBuffer.toString();} catch (Exception e) {LOGGER.error("encrypt()#NoSuchAlgorithmException", e);}return null;}/*** RSA公鑰解密* @param content 等待解密的數據* @param publicKey RSA 公鑰 if null then getPublicKey()* @return 解密后的明文*/public static String decryptByPublic(String content, PublicKey publicKey) {if (publicKey == null) {publicKey = getPublicKey();}try {Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, publicKey);//該密鑰能夠加密的最大字節長度int splitLength = ((RSAPublicKey) publicKey).getModulus().bitLength() / 8;byte[] contentBytes = hexStringToBytes(content);byte[][] arrays = splitBytes(contentBytes, splitLength);StringBuffer stringBuffer = new StringBuffer();String sTemp = null;for (byte[] array : arrays) {stringBuffer.append(new String(cipher.doFinal(array)));}return stringBuffer.toString();} catch (Exception e) {LOGGER.error("encrypt()#NoSuchAlgorithmException", e);}return null;}/*** 根據限定的每組字節長度,將字節數組分組* @param bytes 等待分組的字節組* @param splitLength 每組長度* @return 分組后的字節組*/public static byte[][] splitBytes(byte[] bytes, int splitLength) {//bytes與splitLength的余數int remainder = bytes.length % splitLength;//數據拆分后的組數,余數不為0時加1int quotient = remainder != 0 ? bytes.length / splitLength + 1 : bytes.length / splitLength;byte[][] arrays = new byte[quotient][];byte[] array = null;for (int i = 0; i < quotient; i++) {//如果是最后一組(quotient-1),同時余數不等于0,就將最后一組設置為remainder的長度if (i == quotient - 1 && remainder != 0) {array = new byte[remainder];System.arraycopy(bytes, i * splitLength, array, 0, remainder);} else {array = new byte[splitLength];System.arraycopy(bytes, i * splitLength, array, 0, splitLength);}arrays[i] = array;}return arrays;}/*** 將字節數組轉換成16進制字符串* @param bytes 即將轉換的數據* @return 16進制字符串*/public static String bytesToHexString(byte[] bytes) {StringBuffer sb = new StringBuffer(bytes.length);String temp = null;for (int i = 0; i < bytes.length; i++) {temp = Integer.toHexString(0xFF & bytes[i]);if (temp.length() < 2) {sb.append(0);}sb.append(temp);}return sb.toString();}/*** 將16進制字符串轉換成字節數組* @param hex 16進制字符串* @return byte[]*/public static byte[] hexStringToBytes(String hex) {int len = (hex.length() / 2);hex = hex.toUpperCase();byte[] result = new byte[len];char[] chars = hex.toCharArray();for (int i = 0; i < len; i++) {int pos = i * 2;result[i] = (byte) (toByte(chars[pos]) << 4 | toByte(chars[pos + 1]));}return result;}/*** 將char轉換為byte* @param c char* @return byte*/private static byte toByte(char c) {return (byte) "0123456789ABCDEF".indexOf(c);}public static void mainBak(String[] args) {String s = "test";RSAUtils.generateKeyPair();String c1 = RSAUtils.encryptByPublic(s.getBytes(), null);String m1 = RSAUtils.decryptByPrivate(c1, null);String c2 = RSAUtils.encryptByPrivate(s.getBytes(), null);String m2 = RSAUtils.decryptByPublic(c2, null);System.out.println(c1);System.out.println(m1);System.out.println(c2);System.out.println(m2);}public static void main(String[] args) {String s = "test";Map<String, String> map = RSAUtils.generateKeyPair();String c1 = RSAUtils.encryptByPublic(s.getBytes(), null);String m1 = RSAUtils.decryptByPrivate(c1, null);String c2 = RSAUtils.encryptByPrivate(s.getBytes(), null);String m2 = RSAUtils.decryptByPublic(c2, null);System.out.println(c1);System.out.println(m1);System.out.println(c2);System.out.println(m2);String encryptResult = RSAUtils.encryptByPublic(s.getBytes(), obtainRSAPublicKey(map));System.out.println("encryptResult:" + s + "------" + encryptResult);String decryptResult = RSAUtils.decryptByPrivate(encryptResult, obtainRSAPrivateKey(map));System.out.println("decryptResult:" + s + "------" + decryptResult);}private static RSAPrivateKey obtainRSAPrivateKey(Map<String, String> map) {try {byte[] keyBytes = decoder.decode(map.get("privateKey"));PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);return (RSAPrivateKey) keyFactory.generatePrivate(pkcs8EncodedKeySpec);} catch (InvalidKeySpecException e) {LOGGER.error("getPrivateKey()#" + e.getMessage(), e);}return null;}public static RSAPublicKey obtainRSAPublicKey(Map<String, String> map) {try {byte[] keyBytes = decoder.decode(map.get("publicKey"));X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);return (RSAPublicKey) keyFactory.generatePublic(x509EncodedKeySpec);} catch (InvalidKeySpecException e) {LOGGER.error("getPublicKey()#" + e.getMessage(), e);}return null;}public static String decrypt(String privateKey, String encryptResult) {String decryptResult = RSAUtils.decryptByPrivate(encryptResult, obtainRSAPrivateKey(privateKey));return decryptResult;}private static PrivateKey obtainRSAPrivateKey(String privateKey) {try {byte[] keyBytes = decoder.decode(privateKey);PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);return (RSAPrivateKey) keyFactory.generatePrivate(pkcs8EncodedKeySpec);} catch (InvalidKeySpecException e) {LOGGER.error("getPrivateKey()#" + e.getMessage(), e);}return null;}public static String encryptByPublic(String publicKey, String aesKey) {String encryptResult = RSAUtils.encryptByPublic(aesKey.getBytes(), obtainRSAPublicKey(publicKey));return encryptResult;}private static PublicKey obtainRSAPublicKey(String publicKey) {try {byte[] keyBytes = decoder.decode(publicKey);
//            byte[] keyBytes =publicKey.getBytes();X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);return (RSAPublicKey) keyFactory.generatePublic(x509EncodedKeySpec);} catch (InvalidKeySpecException e) {LOGGER.error("getPublicKey()#" + e.getMessage(), e);}return null;}public static String decryptPem(String privateKeyPEM, String encryptedData)  {try {PrivateKey privateKey = getPrivateKeyFromPEM(privateKeyPEM);String decryptedData = decrypt(encryptedData, privateKey);return  decryptedData;} catch (Exception e) {log.error("解密異常",e);return null;}}/*** RSA解密*/public static String decrypt(String encryptedData, PrivateKey privateKey) throws Exception {Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, privateKey);byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData);byte[] decryptedBytes = cipher.doFinal(encryptedBytes);return new String(decryptedBytes, "UTF-8");}/*** 從PEM格式字符串加載私鑰*/public static PrivateKey getPrivateKeyFromPEM(String privateKeyPEM) throws Exception {// 清理PEM格式的標記和換行符String privateKeyContent = privateKeyPEM.replace("-----BEGIN PRIVATE KEY-----", "").replace("-----END PRIVATE KEY-----", "").replaceAll("\\s", "");byte[] keyBytes = Base64.getDecoder().decode(privateKeyContent);PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance("RSA");return keyFactory.generatePrivate(spec);}}

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>test20250703</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.17.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.4.12</version></dependency><dependency><groupId>org.bouncycastle</groupId><artifactId>bcpkix-jdk15on</artifactId><version>1.59</version></dependency><dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>1.15</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.34</version><scope>provided</scope></dependency></dependencies>
</project>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/89853.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/89853.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/89853.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

PC端基于SpringBoot架構控制無人機(一):初識無人機控制

一、無人機飛控系統的概述飛控&#xff08;Flight Controller&#xff09;是無人機最為核心的組成部分之一&#xff0c;負責實現無人機的自主飛行控制和穩定飛行。飛控系統的功能決定了無人機的飛行性能&#xff0c;包括飛行的穩定性、操控的響應速度、導航的精確度等。通過飛控…

QT6 源(154)模型視圖架構里的列表視圖 QListView:先學習屬性部分,

&#xff08;1&#xff09;屬性總圖&#xff0c;以及測試程序的框架 &#xff1a; 開始屬性的學習 &#xff1a; &#xff08;2&#xff09; 繼續屬性學習 &#xff1a; &#xff08;3&#xff09; 謝謝

MySQL——9、事務管理

事務管理 1、什么是事務&#xff1f;2、事務常見操作方式3、事務隔離級別4、數據庫并發場景4.1、讀-寫4.2、RR與RC的本質區別 1、什么是事務&#xff1f; mysql是基于CS模式的&#xff0c;是一套網絡服務&#xff0c;所以我們是可以在本地連接上遠程服務器的mysql服務端的。my…

Python之面向對象詳解(一篇足矣)

目錄 一、初階面向對象 1. 初識面向對象 1.1 對象和self 1.2 常見成員 1.3 應用示例 將數據封裝到一個對象&#xff0c;便于以后使用。 將數據封裝到對象中&#xff0c;在方法中對原始數據進行加工處理。 根據類創建多個對象&#xff0c;在方法中對對象中的數據進行修改…

【Qt】qml組件對象怎么傳遞給c++

將QML組件對象傳遞給C的方法 在QML和C之間傳遞完整的組件對象需要特殊處理&#xff0c;因為QML組件是動態創建的JavaScript對象。以下是幾種有效的方法&#xff1a; 1. 使用QObject指針傳遞 C端設置 // MyClass.h #include <QObject> #include <QQuickItem>cla…

Java基礎 集合框架 List框架

list架構 list接口list 核心特性以及擴展Collection的體現 抽象類 AbstractList抽象類 AbstractSequentialList (簡化鏈表的順序訪問)AbstractSequentialList 核心特點自定義實現示例代碼講解其實現原理AbstractSequentialList 總結與AbstractList的對比 List 實現類 ArrayList…

2025年6月28和29日復習和預習(C++)

學習筆記大綱?一、預習部分&#xff1a;數組基礎?&#xff08;一&#xff09;核心知識點?數組的創建&#xff1a;掌握一維數組的聲明方式&#xff0c;如int arr[5];&#xff08;創建一個包含 5 個整數的數組&#xff09;。重點在于理解數組長度需為常量&#xff0c;且在聲明…

【centos8服務如何給服務器開發3306端口】

在 CentOS 8 中開放 MySQL 默認端口 3306&#xff0c;需要配置防火墻和 SELinux。以下是詳細步驟&#xff1a; 1. 開放防火墻端口&#xff08;Firewalld&#xff09; CentOS 8 默認使用 firewalld 管理防火墻&#xff0c;執行以下命令開放 3306 端口&#xff1a; # 開放 TCP 33…

python系列之:使用md5和sha256完成簽名認證,調用接口

python系列之:使用md5和sha256完成簽名認證,調用接口 MD5簽名和sha256簽名認證md5認證代碼sha256認證代碼拼接簽名生成簽名拼接url調用接口MD5簽名和sha256簽名認證 MD5簽名認證 算法特性: 生成128位(16字節)的哈希值計算速度快已被證明存在碰撞漏洞(不同輸入可能產生相同…

SpringBatch配置與入門實例

通過對SpringBatch基礎概念的了解&#xff0c;參考&#xff1a;SpringBatch使用介紹 任何技術用起來之后&#xff0c;再去探究內部細節的原理&#xff0c;才會事半功倍。下面記錄一下筆者在SpringBoot項目中集成SpringBatch&#xff0c;并且通過一個小的實例展示如何簡單使用它…

spdlog 項目介紹與二次封裝

目錄 介紹 二次封裝 介紹 spdlog 是C開源的第三方日志庫&#xff0c;整個項目在 spdlog 命名空間中。 在 spdlog 命名空間的 level 命名空間里定義了枚舉類型&#xff0c;把日志分為了 5 個等級&#xff1a;trace debug info warn err critical enum level_enum : in…

shell編程之awk命令詳解

1. awk 教程 1.1 調用 awk awk 是一種強大的文本處理工具&#xff0c;在 Linux 系統中廣泛應用于日志分析、數據處理等場景。調用 awk 主要有以下三種方式&#xff1a; 1.1.1 命令行方式 基本語法為&#xff1a; awk (-F filed-separator) commands input-files其中&#…

服務器需要備案嗎?在哪些地區需要備案?

&#x1f3af; 服務器是否需要備案&#xff1f; 是否需要備案&#xff0c;關鍵看以下兩個因素&#xff1a; 服務器所在地&#xff08;機房位置&#xff09; 網站面向的訪問群體&#xff08;境內或境外&#xff09; &#x1f3f7; 中國大陸&#xff08;境內&#xff09;服務器…

HarmonyOS學習3---ArkUI

1、組件 1.1、基礎組件 1.2、布局容器 1.3、頁面導航 1.4、其他組件 2、ArkTs/C混合開發&#xff0c;高性能編碼 3、布局能力&交互歸一 4、實時開發預覽

Java學習第十五部分——MyBatis

目錄 一.概述 二.特點 三.組件 四.Mapper 五.配置文件 六.使用步驟 七.高級功能 八.優點缺點 九.項目實戰 1.打開idea創建一個Java項目&#xff0c;構建系統選“Maven”? 2.創建完成后若依賴報錯&#xff0c;可通過下載或重新加載來解決? 3.配置pom.xml文件&…

小企業如何搭建本地私有云服務器,并設置內部網絡地址提供互聯網訪問

在數字化時代&#xff0c;很多普通公司小企業規模的&#xff0c;利用本地小型服務器或計算機搭建私有云服務器&#xff0c;不僅可以提升數據管理效率&#xff0c;還能保障業務數據的安全性和靈活性。以下是為小企業量身定制的私有云服務器搭建指南&#xff0c;及最后附無公網IP…

MySQL 八股文【持續更新ing】

MySQL 八股文【持續更新ing】 文章目錄 MySQL 八股文【持續更新ing】前言一、MySQL的存儲引擎有哪些&#xff1f;他們之間有什么區別&#xff1f;二、MySQL InnoDB 引擎中的聚簇索引和非聚簇索引有什么區別&#xff1f;1.InnoDB 中的聚簇索引2.InnoDB 中的非聚簇索引 三、MySQL…

每日算法刷題Day42 7.5:leetcode前綴和3道題,用時2h

7. 3026.最大好子數組和(中等,學習) 3026. 最大好子數組和 - 力扣&#xff08;LeetCode&#xff09; 思想 1.給你一個長度為 n 的數組 nums 和一個 正 整數 k 。 如果 nums 的一個子數組中&#xff0c;第一個元素和最后一個元素 差的絕對值恰好 為 k &#xff0c;我們稱這個…

Linux操作系統之文件(四):文件系統(上)

前言&#xff1a; 我們前幾篇文章講了緩沖區與重定向的有關概念&#xff0c;這些設計是linux系統的核心機制&#xff0c;對系統性能、資源管理和用戶操作靈活性有重要意義。 不涉及一些硬件就不可能讓大家清楚地去理解文件系統&#xff0c;所以這篇文章&#xff0c;我將會從計…

java中,stream的filter和list的removeIf篩選速度比較

在 Java 里&#xff0c;Stream 的filter和 List 的removeIf篩選效率要依據具體情形來判斷。 1. 操作本質有別 Stream 的 filter&#xff1a; 它是一種中間操作&#xff0c;不會立刻執行&#xff0c;而是把篩選條件記錄下來。只有遇到終端操作時&#xff0c;才會開始處理元素。…