【Java万花筒】Java安全卫士:从密码学到Web应用攻击
Java安全锦囊:从Web应用攻击到加密算法,助你建立强固的开发堡垒
前言
在当今数字化时代,安全性至关重要,特别是对于Java开发者而言。本文将深入探讨Java安全与加密领域的关键库和技术,包括Bouncy Castle、Jasypt、Keycloak、Apache Shiro、Java Cryptography Extension (JCE)和OWASP Java Encoder。通过详细介绍各个库的功能、使用案例和实际代码示例,读者将获得在保护应用免受各种威胁方面的深刻理解。
欢迎订阅专栏:Java万花筒
文章目录
- Java安全锦囊:从Web应用攻击到加密算法,助你建立强固的开发堡垒
- **前言**
- 1. Bouncy Castle
- 1.1 密码学算法
- 1.2 提供者架构
- 1.2.1 轻量级 API
- 1.2.2 支持的算法
- 1.3 使用案例
- 1.3.1 安全通信
- 1.3.2 数字签名
- 2. Jasypt(简化的Java加密)
- 2.1 加密方法
- 2.1.1 对称加密
- 2.1.2 非对称加密
- 2.2 在Java应用中的集成
- 2.2.1 配置设置
- 2.2.2 加密属性文件
- 3. Keycloak(身份和访问管理)
- 3.1 身份管理
- 3.1.1 用户认证
- 3.1.2 授权策略
- 3.2 集成
- 3.2.1 单点登录(SSO)
- 3.2.2 访问控制列表(ACLs)
- 4. Apache Shiro
- 4.1 安全框架概述
- 4.1.1 认证与授权
- 4.1.2 会话管理
- 4.2 功能特点
- 4.2.1 加密支持
- 4.2.2 Web应用安全管理
- 5. Java Cryptography Extension (JCE)
- 5.1 JCE架构
- 5.1.1 提供者(Provider)
- 5.1.2 算法(Algorithms)
- 5.2 加密与解密
- 5.2.1 对称加密
- 5.2.2 非对称加密
- 6. OWASP Java Encoder
- 6.1 安全编码实践
- 6.1.1 防止Web应用攻击
- 6.1.2 防止跨站脚本(XSS)攻击
- 6.2 编码技术
- 6.2.1 HTML、URL编码
- 6.2.2 JavaScript编码
- **总结**
1. Bouncy Castle
1.1 密码学算法
Bouncy Castle是一个功能强大的密码学库,支持对称加密、非对称加密、哈希函数等。例如,使用Bouncy Castle进行AES对称加密的示例代码如下:
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.security.Security;
import java.util.Base64;public class BouncyCastleExample {public static void main(String[] args) throws Exception {// 添加Bouncy Castle作为安全提供者Security.addProvider(new BouncyCastleProvider());// 生成AES密钥KeyGenerator keyGen = KeyGenerator.getInstance("AES", "BC");keyGen.init(128);SecretKey secretKey = keyGen.generateKey();// 加密Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");cipher.init(Cipher.ENCRYPT_MODE, secretKey);byte[] encryptedData = cipher.doFinal("Hello, Bouncy Castle!".getBytes());// 解密cipher.init(Cipher.DECRYPT_MODE, secretKey);byte[] decryptedData = cipher.doFinal(encryptedData);// 输出结果System.out.println("Original: " + new String(decryptedData));}
}
1.2 提供者架构
1.2.1 轻量级 API
Bouncy Castle提供了轻量级 API,使加密操作更加简便。以下是一个使用轻量级 API 进行非对称加密的示例:
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.KeyGenerationParameters;
import org.bouncycastle.crypto.engines.RSAEngine;
import org.bouncycastle.crypto.generators.RSAKeyPairGenerator;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import java.security.SecureRandom;public class LightweightAPIExample {public static void main(String[] args) {// 初始化随机数生成器SecureRandom random = new SecureRandom();// 生成RSA密钥对RSAKeyPairGenerator generator = new RSAKeyPairGenerator();generator.init(new KeyGenerationParameters(random, 2048));AsymmetricCipherKeyPair keyPair = generator.generateKeyPair();// 获取公钥和私钥AsymmetricKeyParameter publicKey = keyPair.getPublic();AsymmetricKeyParameter privateKey = keyPair.getPrivate();// 使用公钥进行加密RSAEngine rsaEngine = new RSAEngine();CipherParameters params = new ParametersWithRandom(publicKey, random);rsaEngine.init(true, params);byte[] encryptedData = rsaEngine.processBlock("Hello, Lightweight API!".getBytes(), 0, "Hello, Lightweight API!".getBytes().length);// 使用私钥进行解密rsaEngine.init(false, privateKey);byte[] decryptedData = rsaEngine.processBlock(encryptedData, 0, encryptedData.length);// 输出结果System.out.println("Original: " + new String(decryptedData));}
}
1.2.2 支持的算法
Bouncy Castle支持多种密码学算法,包括对称加密、非对称加密、签名算法等。以下是一个使用Bouncy Castle进行SHA256哈希的示例:
import org.bouncycastle.jcajce.provider.digest.SHA256;
import java.security.MessageDigest;public class SupportedAlgorithmsExample {public static void main(String[] args) throws Exception {// 创建SHA-256消息摘要对象MessageDigest sha256 = MessageDigest.getInstance("SHA-256", "BC");// 计算消息摘要byte[] hashedData = sha256.digest("Hello, Bouncy Castle!".getBytes());// 输出结果System.out.println("SHA-256 Hash: " + Base64.getEncoder().encodeToString(hashedData));}
}
1.3 使用案例
1.3.1 安全通信
Bouncy Castle可用于安全通信,下面是一个使用Bouncy Castle进行安全通信的简单示例,其中使用AES对称加密算法:
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.security.Security;
import java.util.Base64;public class SecureCommunicationExample {public static void main(String[] args) throws Exception {// 添加Bouncy Castle作为安全提供者Security.addProvider(new BouncyCastleProvider());// 生成AES密钥KeyGenerator keyGen = KeyGenerator.getInstance("AES", "BC");keyGen.init(128);SecretKey secretKey = keyGen.generateKey();// 模拟发送方加密Cipher senderCipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");senderCipher.init(Cipher.ENCRYPT_MODE, secretKey);byte[] encryptedData = senderCipher.doFinal("Hello, Bouncy Castle!".getBytes());// 模拟接收方解密Cipher receiverCipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");receiverCipher.init(Cipher.DECRYPT_MODE, secretKey);byte[] decryptedData = receiverCipher.doFinal(encryptedData);// 输出结果System.out.println("Original Message: " + new String(decryptedData));}
}
1.3.2 数字签名
Bouncy Castle支持数字签名,下面是一个使用Bouncy Castle进行数字签名和验证的示例:
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.Signature;public class DigitalSignatureExample {public static void main(String[] args) throws Exception {// 添加Bouncy Castle作为安全提供者Security.addProvider(new BouncyCastleProvider());// 生成RSA密钥对KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", "BC");keyPairGenerator.initialize(2048);KeyPair keyPair = keyPairGenerator.generateKeyPair();PublicKey publicKey = keyPair.getPublic();PrivateKey privateKey = keyPair.getPrivate();// 创建数字签名对象Signature signature = Signature.getInstance("SHA256withRSA", "BC");signature.initSign(privateKey);// 要签名的数据byte[] dataToSign = "Hello, Digital Signature!".getBytes();signature.update(dataToSign);// 生成数字签名并获取签名结果:byte[] digitalSignature = signature.sign();// 验证数字签名Signature verifier = Signature.getInstance("SHA256withRSA", "BC");verifier.initVerify(publicKey);verifier.update(dataToSign);// 验证签名boolean verified = verifier.verify(digitalSignature);// 输出结果System.out.println("Digital Signature Verified: " + verified);}
}
2. Jasypt(简化的Java加密)
2.1 加密方法
2.1.1 对称加密
Jasypt支持对称加密算法,以下是一个使用Jasypt进行AES对称加密的示例:
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;public class JasyptSymmetricEncryptionExample {public static void main(String[] args) {// 创建Jasypt加密器StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();encryptor.setPassword("secret"); // 设置加密密码// 加密String encryptedText = encryptor.encrypt("Hello, Jasypt!");System.out.println("Encrypted Text: " + encryptedText);// 解密String decryptedText = encryptor.decrypt(encryptedText);System.out.println("Decrypted Text: " + decryptedText);}
}
2.1.2 非对称加密
Jasypt也支持非对称加密算法,以下是一个使用Jasypt进行RSA非对称加密的示例:
import org.jasypt.encryption.pbe.StandardPBEByteEncryptor;
import org.jasypt.encryption.pbe.config.SimplePBEByteEncryptorConfig;import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.util.Base64;public class JasyptAsymmetricEncryptionExample {public static void main(String[] args) throws Exception {// 生成RSA密钥对KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");keyPairGenerator.initialize(2048);KeyPair keyPair = keyPairGenerator.generateKeyPair();// 创建Jasypt加密器StandardPBEByteEncryptor encryptor = new StandardPBEByteEncryptor();encryptor.setAlgorithm("RSA");encryptor.setPublicKey(Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded()));encryptor.setPrivateKey(Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded()));encryptor.setConfig(new SimplePBEByteEncryptorConfig());// 加密byte[] encryptedData = encryptor.encrypt("Hello, Jasypt!".getBytes());// 解密byte[] decryptedData = encryptor.decrypt(encryptedData);System.out.println("Decrypted Text: " + new String(decryptedData));}
}
2.2 在Java应用中的集成
2.2.1 配置设置
Jasypt的集成相对简单,通常只需要在应用的配置中添加相应的密码配置。以下是一个使用Jasypt进行数据库连接密码加密的示例:
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;public class JasyptIntegrationExample {public static void main(String[] args) {// 创建Jasypt加密器StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();encryptor.setPassword("mySecretKey"); // 设置加密密码// 加密数据库连接密码String encryptedPassword = encryptor.encrypt("myDatabasePassword");System.out.println("Encrypted Database Password: " + encryptedPassword);// 在应用配置中使用加密后的密码// dataSource.password=ENC(加密后的密码)}
}
2.2.2 加密属性文件
Jasypt还支持加密整个属性文件,以下是一个使用Jasypt进行属性文件加密的示例:
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig;import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;public class JasyptPropertyEncryptionExample {public static void main(String[] args) throws IOException {// 创建Jasypt加密器StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();EnvironmentStringPBEConfig config = new EnvironmentStringPBEConfig();config.setPasswordEnvName("MY_SECRET_KEY_ENV"); // 设置加密密码环境变量encryptor.setConfig(config);// 加密属性文件encryptPropertiesFile("path/to/my.properties", encryptor);}private static void encryptPropertiesFile(String filePath, StandardPBEStringEncryptor encryptor) throws IOException {Properties properties = new Properties();// 读取原始属性文件try (InputStream input = new FileInputStream(filePath)) {properties.load(input);}// 加密敏感属性properties.setProperty("db.password", encryptor.encrypt(properties.getProperty("db.password")));// 保存加密后的属性文件try (FileOutputStream output = new FileOutputStream(filePath)) {properties.store(output, null);}}
}
3. Keycloak(身份和访问管理)
3.1 身份管理
3.1.1 用户认证
Keycloak提供了强大的用户认证功能,以下是一个简单的Keycloak用户认证示例:
import org.keycloak.KeycloakPrincipal;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
import org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;public class KeycloakAuthenticationExample {public static void main(String[] args) {// 获取当前身份验证信息Authentication authentication = SecurityContextHolder.getContext().getAuthentication();// 从身份验证信息中获取KeycloakPrincipalKeycloakPrincipal<KeycloakSecurityContext> keycloakPrincipal =(KeycloakPrincipal<KeycloakSecurityContext>) authentication.getPrincipal();// 获取用户IDString userId = keycloakPrincipal.getKeycloakSecurityContext().getToken().getSubject();System.out.println("User ID: " + userId);// 获取用户名String username = keycloakPrincipal.getKeycloakSecurityContext().getToken().getPreferredUsername();System.out.println("Username: " + username);}
}
3.1.2 授权策略
Keycloak支持灵活的授权策略,可以通过设置角色、资源和策略来实现精确的授权。以下是一个使用Keycloak进行基于角色的授权的示例:
import org.keycloak.KeycloakPrincipal;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;public class KeycloakAuthorizationExample {public static void main(String[] args) {// 获取当前身份验证信息Authentication authentication = SecurityContextHolder.getContext().getAuthentication();// 从身份验证信息中获取KeycloakPrincipalKeycloakPrincipal<KeycloakSecurityContext> keycloakPrincipal =(KeycloakPrincipal<KeycloakSecurityContext>) authentication.getPrincipal();// 检查用户是否具有某个角色boolean isAdmin = keycloakPrincipal.getKeycloakSecurityContext().getToken().getRealmAccess().isUserInRole("admin");System.out.println("Is Admin: " + isAdmin);// 检查用户是否具有特定资源的访问权限boolean hasAccess = keycloakPrincipal.getKeycloakSecurityContext().getToken().getResourceAccess("my-resource").isGranted("read");System.out.println("Has Read Access: " + hasAccess);}
}
3.2 集成
3.2.1 单点登录(SSO)
Keycloak支持单点登录(SSO),以下是一个使用Keycloak进行单点登录的示例:
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;public class KeycloakSSOExample {public static void main(String[] args) {// 获取当前身份验证信息Authentication authentication = SecurityContextHolder.getContext().getAuthentication();// 从身份验证信息中获取KeycloakSecurityContextKeycloakSecurityContext keycloakSecurityContext =((SimpleKeycloakAccount) authentication.getDetails()).getKeycloakSecurityContext();// 获取SSO Session IDString sessionID = keycloakSecurityContext.getToken().getSessionState();System.out.println("SSO Session ID: " + sessionID);}
}
3.2.2 访问控制列表(ACLs)
Keycloak支持访问控制列表(ACLs),以下是一个使用Keycloak进行基于ACL的访问控制的示例:
import org.keycloak.KeycloakPrincipal;
import org.keycloak.KeycloakSecurityContext;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;public class KeycloakACLExample {public static void main(String[] args) {// 获取当前身份验证信息Authentication authentication = SecurityContextHolder.getContext().getAuthentication();// 从身份验证信息中获取KeycloakPrincipalKeycloakPrincipal<KeycloakSecurityContext> keycloakPrincipal =(KeycloakPrincipal<KeycloakSecurityContext>) authentication.getPrincipal();// 获取用户IDString userId = keycloakPrincipal.getKeycloakSecurityContext().getToken().getSubject();// 根据用户ID检查访问控制列表(ACLs)boolean hasAccess = checkACLs(userId);System.out.println("Has Access: " + hasAccess);}private static boolean checkACLs(String userId) {// 实现自定义的访问控制逻辑,根据用户ID判断是否有访问权限// 返回true表示有权限,返回false表示无权限// 可以根据实际需求连接数据库或其他服务进行权限验证// 示例中简单返回truereturn true;}
}
4. Apache Shiro
4.1 安全框架概述
4.1.1 认证与授权
Apache Shiro提供了简化的认证和授权,以下是一个使用Apache Shiro进行基本认证和授权的示例:
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;public class ShiroAuthenticationAuthorizationExample {public static void main(String[] args) {// 从配置文件创建SecurityManagerIniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");SecurityManager securityManager = factory.getInstance();SecurityUtils.setSecurityManager(securityManager);// 获取当前用户Subject currentUser = SecurityUtils.getSubject();// 登录UsernamePasswordToken token = new UsernamePasswordToken("user", "password");try {currentUser.login(token);System.out.println("Login successful!");} catch (UnknownAccountException uae) {System.out.println("Unknown account");} catch (IncorrectCredentialsException ice) {System.out.println("Incorrect credentials");} catch (LockedAccountException lae) {System.out.println("Account is locked");} catch (AuthenticationException ae) {System.out.println("Authentication error");}// 检查用户是否具有某个角色if (currentUser.hasRole("admin")) {System.out.println("User has admin role");} else {System.out.println("User does not have admin role");}// 检查用户是否具有某个权限if (currentUser.isPermitted("read:documents")) {System.out.println("User has read permission for documents");} else {System.out.println("User does not have read permission for documents");}// 登出currentUser.logout();}
}
4.1.2 会话管理
Apache Shiro提供了灵活的会话管理,以下是一个使用Apache Shiro进行会话管理的示例:
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;public class ShiroSessionManagementExample {public static void main(String[] args) {// 从配置文件创建SecurityManagerIniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");SecurityManager securityManager = factory.getInstance();SecurityUtils.setSecurityManager(securityManager);// 获取当前用户Subject currentUser = SecurityUtils.getSubject();// 登录UsernamePasswordToken token = new UsernamePasswordToken("user", "password");currentUser.login(token);// 获取会话Session session = currentUser.getSession();// 设置和获取会话属性session.setAttribute("key", "value");String value = (String) session.getAttribute("key");System.out.println("Session Attribute Value: " + value);// 获取会话超时时间long timeout = session.getTimeout();System.out.println("Session Timeout: " + timeout + " milliseconds");// 会话过期后,用户需要重新认证// 模拟会话过期session.setTimeout(1000);try {// 在会话过期后尝试访问会话属性,将触发会话过期异常String expiredValue = (String) session.getAttribute("key");} catch (org.apache.shiro.session.ExpiredSessionException e) {System.out.println("Session has expired");}// 登出currentUser.logout();}
}
4.2 功能特点
4.2.1 加密支持
Apache Shiro内置了加密支持,以下是一个使用Shiro进行密码加密和验证的示例:
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;public class ShiroEncryptionExample {public static void main(String[] args) {// 从配置文件创建SecurityManagerIniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");SecurityManager securityManager = factory.getInstance();SecurityUtils.setSecurityManager(securityManager);// 获取当前用户Subject currentUser = SecurityUtils.getSubject();// 登录UsernamePasswordToken token = new UsernamePasswordToken("user", "password");currentUser.login(token);// 加密密码String plainTextPassword = "password";String salt = "salt";int hashIterations = 1000;String hashedPassword = new SimpleHash("SHA-256", plainTextPassword, salt, hashIterations).toString();System.out.println("Hashed Password: " + hashedPassword);// 验证密码boolean passwordMatch = currentUser.isPermitted("user:password:" + hashedPassword);System.out.println("Password Match: " + passwordMatch);// 登出currentUser.logout();}
}
4.2.2 Web应用安全管理
Apache Shiro提供了完善的Web应用安全管理,以下是一个使用Shiro进行基本Web应用安全管理的示例:
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;public class ShiroWebSecurityExample {public static void main(String[] args) {// 从配置文件创建SecurityManagerIniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro-web.ini");SecurityManager securityManager = factory.getInstance();SecurityUtils.setSecurityManager(securityManager);// 获取当前用户Subject currentUser = SecurityUtils.getSubject();// 检查用户是否已认证if (currentUser.isAuthenticated()) {System.out.println("User is authenticated");} else {System.out.println("User is not authenticated");}// 检查用户是否具有某个角色if (currentUser.hasRole("admin")) {System.out.println("User has admin role");} else {System.out.println("User does not have admin role");}// 检查用户是否具有某个权限if (currentUser.isPermitted("read:documents")) {System.out.println("User has read permission for documents");} else {System.out.println("User does not have read permission for documents");}}
}
5. Java Cryptography Extension (JCE)
5.1 JCE架构
5.1.1 提供者(Provider)
Java Cryptography Extension (JCE)采用提供者架构,以下是一个使用JCE进行SHA-256哈希的示例:
import java.security.MessageDigest;
import java.security.Security;
import java.util.Base64;public class JCEProviderExample {public static void main(String[] args) throws Exception {// 添加Bouncy Castle作为安全提供者Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());// 创建SHA-256消息摘要对象MessageDigest sha256 = MessageDigest.getInstance("SHA-256");// 计算消息摘要byte[] hashedData = sha256.digest("Hello, JCE!".getBytes());// 输出结果System.out.println("SHA-256 Hash: " + Base64.getEncoder().encodeToString(hashedData));}
}
5.1.2 算法(Algorithms)
JCE提供了丰富的加密算法,以下是一个使用JCE进行AES对称加密的示例:
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.security.Security;
import java.util.Base64;public class JCEAlgorithmsExample {public static void main(String[] args) throws Exception {// 添加Bouncy Castle作为安全提供者Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());// 生成AES密钥KeyGenerator keyGen = KeyGenerator.getInstance("AES");keyGen.init(128);SecretKey secretKey = keyGen.generateKey();// 加密Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");cipher.init(Cipher.ENCRYPT_MODE, secretKey);byte[] encryptedData = cipher.doFinal("Hello, JCE!".getBytes());// 解密cipher.init(Cipher.DECRYPT_MODE, secretKey);byte[] decryptedData = cipher.doFinal(encryptedData);// 输出结果System.out.println("Original: " + new String(decryptedData));}
}
5.2 加密与解密
5.2.1 对称加密
JCE支持对称加密算法,以下是一个使用JCE进行AES对称加密的示例:
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.util.Base64;public class JCESymmetricEncryptionExample {public static void main(String[] args) throws Exception {// 生成AES密钥KeyGenerator keyGen = KeyGenerator.getInstance("AES");keyGen.init(128);SecretKey secretKey = keyGen.generateKey();// 加密Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");cipher.init(Cipher.ENCRYPT_MODE, secretKey);byte[] encryptedData = cipher.doFinal("Hello, JCE!".getBytes());// 解密cipher.init(Cipher.DECRYPT_MODE, secretKey);byte[] decryptedData = cipher.doFinal(encryptedData);// 输出结果System.out.println("Original: " + new String(decryptedData));}
}
5.2.2 非对称加密
JCE提供了非对称加密算法的支持,以下是一个使用JCE进行RSA非对称加密的示例:
import javax.crypto.Cipher;
import java.security.*;public class JCEAsymmetricEncryptionExample {public static void main(String[] args) throws Exception {// 生成RSA密钥对KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");keyPairGenerator.initialize(2048);KeyPair keyPair = keyPairGenerator.generateKeyPair();// 获取公钥和私钥PublicKey publicKey = keyPair.getPublic();PrivateKey privateKey = keyPair.getPrivate();// 加密Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");cipher.init(Cipher.ENCRYPT_MODE, publicKey);byte[] encryptedData = cipher.doFinal("Hello, JCE!".getBytes());// 解密cipher.init(Cipher.DECRYPT_MODE, privateKey);byte[] decryptedData = cipher.doFinal(encryptedData);// 输出结果System.out.println("Original: " + new String(decryptedData));}
}
6. OWASP Java Encoder
6.1 安全编码实践
6.1.1 防止Web应用攻击
OWASP Java Encoder提供了安全的编码方法,防止Web应用中的攻击,以下是一个使用OWASP Java Encoder进行HTML编码的示例:
import org.owasp.encoder.Encode;public class OWASPJavaEncoderExample {public static void main(String[] args) {// 要编码的文本String userInput = "<script>alert('XSS')</script>";// HTML编码String encodedHTML = Encode.forHtml(userInput);// 输出结果System.out.println("Encoded HTML: " + encodedHTML);}
}
6.1.2 防止跨站脚本(XSS)攻击
OWASP Java Encoder可以防止跨站脚本(XSS)攻击,以下是一个使用OWASP Java Encoder进行JavaScript编码的示例:
import org.owasp.encoder.Encode;public class OWASPJavaEncoderXSSExample {public static void main(String[] args) {// 要编码的文本String userInput = "<script>alert('XSS')</script>";// JavaScript编码String encodedJS = Encode.forJavaScript(userInput);// 输出结果System.out.println("Encoded JavaScript: " + encodedJS);}
}
6.2 编码技术
6.2.1 HTML、URL编码
OWASP Java Encoder提供了HTML和URL编码方法,以下是一个使用OWASP Java Encoder进行URL编码的示例:
import org.owasp.encoder.Encode;public class OWASPJavaEncoderURLEncodingExample {public static void main(String[] args) {// 要编码的文本String userInput = "https://example.com/?query=<script>alert('XSS')</script>";// URL编码String encodedURL = Encode.forUriComponent(userInput);// 输出结果System.out.println("Encoded URL: " + encodedURL);}
}
6.2.2 JavaScript编码
OWASP Java Encoder提供了JavaScript编码方法,以下是一个使用OWASP Java Encoder进行JavaScript编码的示例:
import org.owasp.encoder.Encode;public class OWASPJavaEncoderJavaScriptExample {public static void main(String[] args) {// 要编码的文本String userInput = "alert('XSS')";// JavaScript编码String encodedJS = Encode.forJavaScript(userInput);// 输出结果System.out.println("Encoded JavaScript: " + encodedJS);}
}
这些示例涵盖了常见的Java安全与加密库,包括Bouncy Castle、Jasypt、Keycloak、Apache Shiro、Java Cryptography Extension (JCE)和OWASP Java Encoder。这些库提供了丰富的功能,可用于实现安全的通信、加密解密、身份认证授权以及防范Web应用攻击。
总结
通过学习本文介绍的Java安全与加密库,Java开发者可以更好地保障其应用程序的安全性。无论是实现安全通信、数字签名,还是加密密码、防范Web应用攻击,这些库都为开发者提供了灵活而强大的工具。在数字化环境中,深入了解这些安全技术将成为Java开发者提高应用程序安全性的不可或缺的一部分。
相关文章:
【Java万花筒】Java安全卫士:从密码学到Web应用攻击
Java安全锦囊:从Web应用攻击到加密算法,助你建立强固的开发堡垒 前言 在当今数字化时代,安全性至关重要,特别是对于Java开发者而言。本文将深入探讨Java安全与加密领域的关键库和技术,包括Bouncy Castle、Jasypt、Ke…...

redis安装-Linux为例
可以下载一个Shell或者MobaXterm工具,便于操作 在redis官网下载压缩包 开始安装 安装依赖 yum install -y gcc tcl切换目录 切换目录后直接把redis安装包拖到/user/local/src/下 cd /user/local/src/解压然后安装 #解压 tar -zxvf redis-7.2.4.tar.gz #安装 …...
iOS长按时无法保存图片问题解决方案
在使用iOS设备的用户中,相信很多人都有过在浏览网页时遇到长按时无法保存图片的困扰。这主要是因为网页开发者为了保护版权或隐私,默认屏蔽掉了图片长按时保存的功能。 具体来说,问题出在-webkit-touch-callout这个CSS属性上。这个属性用于定…...
Datawhale 强化学习笔记(一)
参考 在线阅读文档 github 教程 开源框架 JoyRL datawhalechina/joyrl: An easier PyTorch deep reinforcement learning library. (github.com) 策略梯度算法的两种不同的推导版本。 强化学习中的一些核心问题,比如优化值的估计、解决探索与利用等问题。 从传统强…...

首届PolarDB开发者大会在京举办,阿里云李飞飞:云数据库加速迈向智能化
1月17日,阿里云PolarDB开发者大会在京举办,中国首款自研云原生数据库PolarDB发布“三层分离”新版本,基于智能决策实现查询性能10倍提升、节省50%成本。此外,阿里云全新推出数据库场景体验馆、训练营等系列新举措,广大…...
003-90-15【SparkSQLDFDS】慈航寺庙山脚下八卦田旁油菜花海深处人家王大爷家女儿用GPT学习DataSet的基本操作
003-90-14【SparkSQL&DF&DS】慈航寺庙山脚下八卦田旁油菜花海深处人家王大爷家女儿用GPT学习DataSet的基本操作 【SparkSQL&DF&DS】Dataset 的创建和使用 【SparkSQL&DF&DS】2,Dataset 的创建和使用1, 创建2, show3, map4, as5, select6 f…...

代码随想录-刷题第五十七天
42. 接雨水 题目链接:42. 接雨水 思路:本题十分经典,使用单调栈需要理解的几个问题: 首先单调栈是按照行方向来计算雨水,如图: 使用单调栈内元素的顺序 从大到小还是从小到大呢? 从栈头&…...
flutter 播放SVGA动图
SVGAPlayer-Flutter:这是一个轻量级的动画渲染库,可以通过Flutter CustomPainter原生渲染动画,为您带来高性能,低成本的动画体验123。 您可以按照以下步骤使用 SVGAPlayer-Flutter 插件: 1.在 pubspec.yaml 文件中添…...

鸿蒙开发软件汉化
一、打开设置 File>Settings>Plugins>Marketplace,输入Chinese搜索插件(有的人是搜不到的),但别慌,选择Marketplace傍边的 Installed 按钮,里面就有Chinese插件(如果搜索出来的东西比较多往下就可…...

Three.js Tri-panner (三面贴图) 材质 两种实现方式
文章目录 介绍自定义shaderNodeMaterial骨骼材质特殊处理 介绍 Tri-panner 在babylonjs中有支持 但是three.js目前的基础材质并不支持 需要自己定义shader 或者使用目前还没有什么完善的文档的 NodeMaterial 下面展示两种实现方式 自定义shader /*** description: 替换三角面…...

Docker部署Flask项目
Docker部署Flask项目 一、准备项目代码二、编写Dockerfile三、服务器部署 一、准备项目代码 这里写了一个简单的Flask的demo,源代码如下: from flask import Flaskapp Flask(__name__)app.route("/") def index():return "<h1 styl…...

Git将某个文件合并到指定分支
企业开发中,经常会单独拉分支去做自己的需求开发,但是某些时候一些公共的配置我们需要从主线pull,这时候整个分支merge显然不合适 1.切换至待合并文件的分支 git checkout <branch>2.将目标分支的单个文件合并到当前分支 git checkou…...

Dockerfile构建镜像以及阿里云上传
前言 我们在使用docker部署微服务项目的时候会发现这样一个问题:每个服务构建出的镜像文件都很大,几百M,有些原始镜像也已经占据了很多内存了... 这种大的镜像往往都会导致迁移的速度变慢。其实我们启动容器主要最需要的镜像是jdk࿰…...

锂离子电池建模综述
锂电池很有吸引力,因为在元素周期表中,锂是一种非常正电的元素,它也恰好是最轻的金属,密度是水的一半。通常,电池由串联/并联的电化学电池组成。每个电池都包含一个负极(放电时为阳极)和一个由电…...
获取淘宝商品销量数据的方法分享(API、爬虫技术)
随着电子商务的飞速发展,获取淘宝商品销量数据的需求越来越强烈。无论是商家、分析师还是研究人员,都需要这些数据来了解市场趋势、竞争对手情况以及制定营销策略。本文将分享如何通过API和爬虫技术获取淘宝商品销量数据。 一、API获取数据 淘宝开放平…...

android 自定义八边形进度条
自定义八边形动画效果图如下 绘制步骤: 1.先绘制橙色底部八边形实心 2.黑色画笔绘制第二层,让最外层显示一条线条宽度即可 3.再用黄色画笔绘制黄色部分 4.使用渐变画笔根据当前进度绘制覆盖黄色部分 5.使用黑色画笔根据当前进度绘制刻度条 6.黑色画笔绘制…...

域名群站开源系统分享开源域名授权系统
一、需要自己安装PHP和MYSQL服务器环境。 二、务必设置伪静态规则,否则将无法访问文章栏目页面。 三、启用伪静态功能,请在站点设置中选择使用thinkphp的伪静态规则。 四、在域名的根目录下找到”data/config.php”文件,填入数据库的账号和…...
CTF - Web 干货
目录 1、php反序列化之pop链构造 2、常见php伪协议的使用 (1)php://filter (2)php://input 3、文件上传常规操作 (1) 前端绕过 (2) 修改文件类型 (3) 配合.user.ini 或.htaccess解析 (4) 爆破可解析后缀 (5) 针对Windows…...

mobi文件怎么转换成pdf?
mobi文件怎么转换成pdf?在数字化时代,电子书籍成为了越来越受欢迎的阅读方式。我们可以通过多种格式的电子书来获取知识和娱乐,其中一种常见的格式就是Mobi文件。Mobi文件是亚马逊公司开发的一种电子书格式,它主要用于Kindle设备和…...
spakr 提交任务
当前集群支持3中集群管理 Standalone(spak框架自身拥有能力)Apache Mesos Hadoop YARN Kubernetes 使用/spark-submit脚本提交任务,脚本后面可以接参数 ./bin/spark-submit \--class <main-class> \--master <master-url> \--de…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...

使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...

汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

windows系统MySQL安装文档
概览:本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容,为学习者提供全面的操作指导。关键要点包括: 解压 :下载完成后解压压缩包,得到MySQL 8.…...

在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...