【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…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...

苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...

Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...

基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...