| 对称加密算法就是传统的用一个密码进行加密和解密 |
| |
| 根据算法名称/工作模式/填充模式获取Cipher实例; |
| 根据算法名称初始化一个SecretKey实例,密钥必须是指定长度; |
| 使用SerectKey初始化Cipher实例,并设置加密或解密模式; |
| 传入明文或密文,获得密文或明文。 |
算法 |
密钥长度 |
工作模式 |
填充模式 |
DES |
56/64 |
ECB/CBC/PCBC/CTR/... |
NoPadding/PKCS5Padding/... |
AES |
128/192/256 |
ECB/CBC/PCBC/CTR/... |
NoPadding/PKCS5Padding/PKCS7Padding/... |
IDEA |
128 |
ECB |
PKCS5Padding/PKCS7Padding/... |
| import java.security.*; |
| import java.util.Base64; |
| import javax.crypto.*; |
| import javax.crypto.spec.*; |
| |
| public class Main { |
| public static void main(String[] args) throws Exception { |
| |
| String message = "Hello, world!"; |
| System.out.println("Message: " + message); |
| |
| byte[] key = "1234567890abcdef".getBytes("UTF-8"); |
| |
| byte[] data = message.getBytes("UTF-8"); |
| byte[] encrypted = encrypt(key, data); |
| System.out.println("Encrypted: " + Base64.getEncoder().encodeToString(encrypted)); |
| |
| byte[] decrypted = decrypt(key, encrypted); |
| System.out.println("Decrypted: " + new String(decrypted, "UTF-8")); |
| } |
| |
| |
| public static byte[] encrypt(byte[] key, byte[] input) throws GeneralSecurityException { |
| Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); |
| SecretKey keySpec = new SecretKeySpec(key, "AES"); |
| cipher.init(Cipher.ENCRYPT_MODE, keySpec); |
| return cipher.doFinal(input); |
| } |
| |
| |
| public static byte[] decrypt(byte[] key, byte[] input) throws GeneralSecurityException { |
| Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); |
| SecretKey keySpec = new SecretKeySpec(key, "AES"); |
| cipher.init(Cipher.DECRYPT_MODE, keySpec); |
| return cipher.doFinal(input); |
| } |
| } |
| # 控制台 |
| Message: Hello, world! |
| Encrypted: 2xiGROlFBhC57b7EGu5c3g== |
| Decrypted: Hello, world! |
| # ECB模式是最简单的AES加密模式,它只需要一个固定长度的密钥,固定的明文会生成固定的密文,这种一对一的加密方式会导致安全性降低 |
| # 更好的方式是通过CBC模式,它需要一个随机数作为IV参数,这样对于同一份明文,每次生成的密文都不同 |
| |
| import java.security.*; |
| import java.util.Base64; |
| import javax.crypto.*; |
| import javax.crypto.spec.*; |
| |
| public class Main { |
| public static void main(String[] args) throws Exception { |
| |
| String message = "Hello, world!"; |
| System.out.println("Message: " + message); |
| |
| byte[] key = "1234567890abcdef1234567890abcdef".getBytes("UTF-8"); |
| |
| byte[] data = message.getBytes("UTF-8"); |
| byte[] encrypted = encrypt(key, data); |
| System.out.println("Encrypted: " + Base64.getEncoder().encodeToString(encrypted)); |
| |
| byte[] decrypted = decrypt(key, encrypted); |
| System.out.println("Decrypted: " + new String(decrypted, "UTF-8")); |
| } |
| |
| |
| public static byte[] encrypt(byte[] key, byte[] input) throws GeneralSecurityException { |
| Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); |
| SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); |
| |
| SecureRandom sr = SecureRandom.getInstanceStrong(); |
| byte[] iv = sr.generateSeed(16); |
| IvParameterSpec ivps = new IvParameterSpec(iv); |
| cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivps); |
| byte[] data = cipher.doFinal(input); |
| |
| return join(iv, data); |
| } |
| |
| |
| public static byte[] decrypt(byte[] key, byte[] input) throws GeneralSecurityException { |
| |
| byte[] iv = new byte[16]; |
| byte[] data = new byte[input.length - 16]; |
| System.arraycopy(input, 0, iv, 0, 16); |
| System.arraycopy(input, 16, data, 0, data.length); |
| |
| Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); |
| SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); |
| IvParameterSpec ivps = new IvParameterSpec(iv); |
| cipher.init(Cipher.DECRYPT_MODE, keySpec, ivps); |
| return cipher.doFinal(data); |
| } |
| |
| public static byte[] join(byte[] bs1, byte[] bs2) { |
| byte[] r = new byte[bs1.length + bs2.length]; |
| System.arraycopy(bs1, 0, r, 0, bs1.length); |
| System.arraycopy(bs2, 0, r, bs1.length, bs2.length); |
| return r; |
| } |
| } |
| # 控制台 |
| Message: Hello, world! |
| Encrypted: YPMN+yr8fMTmutXZC0HkMPiT3+p1SiAWUwmnUBPaOhg= |
| Decrypted: Hello, world! |
| # PBE的作用就是把用户输入的口令和一个安全随机的口令采用杂凑后计算出真正的密钥 |
| # 以AES密钥为例,我们让用户输入一个口令,然后生成一个随机数,通过PBE算法计算出真正的AES口令,再进行加密 |
| |
| public class Main { |
| public static void main(String[] args) throws Exception { |
| |
| Security.addProvider(new BouncyCastleProvider()); |
| |
| String message = "Hello, world!"; |
| |
| String password = "hello12345"; |
| |
| byte[] salt = SecureRandom.getInstanceStrong().generateSeed(16); |
| System.out.printf("salt: %032x\n", new BigInteger(1, salt)); |
| |
| byte[] data = message.getBytes("UTF-8"); |
| byte[] encrypted = encrypt(password, salt, data); |
| System.out.println("encrypted: " + Base64.getEncoder().encodeToString(encrypted)); |
| |
| byte[] decrypted = decrypt(password, salt, encrypted); |
| System.out.println("decrypted: " + new String(decrypted, "UTF-8")); |
| } |
| |
| |
| public static byte[] encrypt(String password, byte[] salt, byte[] input) throws GeneralSecurityException { |
| PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray()); |
| SecretKeyFactory skeyFactory = SecretKeyFactory.getInstance("PBEwithSHA1and128bitAES-CBC-BC"); |
| SecretKey skey = skeyFactory.generateSecret(keySpec); |
| PBEParameterSpec pbeps = new PBEParameterSpec(salt, 1000); |
| Cipher cipher = Cipher.getInstance("PBEwithSHA1and128bitAES-CBC-BC"); |
| cipher.init(Cipher.ENCRYPT_MODE, skey, pbeps); |
| return cipher.doFinal(input); |
| } |
| |
| |
| public static byte[] decrypt(String password, byte[] salt, byte[] input) throws GeneralSecurityException { |
| PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray()); |
| SecretKeyFactory skeyFactory = SecretKeyFactory.getInstance("PBEwithSHA1and128bitAES-CBC-BC"); |
| SecretKey skey = skeyFactory.generateSecret(keySpec); |
| PBEParameterSpec pbeps = new PBEParameterSpec(salt, 1000); |
| Cipher cipher = Cipher.getInstance("PBEwithSHA1and128bitAES-CBC-BC"); |
| cipher.init(Cipher.DECRYPT_MODE, skey, pbeps); |
| return cipher.doFinal(input); |
| } |
| } |
| # 控制台 |
| salt: 5b30333ac3430c154d3599d65b21ba88 |
| encrypted: 72w120W+7GdCGRWJByZ5Xw== |
| decrypted: Hello, world! |
| public class EncodingUtil { |
| |
| |
| private static final String KEY = "yflyyflyyflyyfly"; |
| |
| |
| |
| |
| public static byte[] md5Encoding(String str) { |
| try { |
| MessageDigest md = MessageDigest.getInstance("MD5"); |
| byte[] digest = md.digest(str.getBytes()); |
| return digest; |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| return null; |
| } |
| |
| |
| |
| |
| public static String psdEncoding(String password, String phone) { |
| byte[] md5Encoding = md5Encoding(password+phone); |
| return new BigInteger(md5Encoding).toString(16); |
| } |
| |
| |
| |
| |
| public static String aesEncoding(String msg) { |
| if(msg == null) { |
| throw new RuntimeException("加密字符串不能为空"); |
| } |
| try { |
| Cipher cipher = Cipher.getInstance("AES"); |
| Key key = new SecretKeySpec(KEY.getBytes(), "AES"); |
| cipher.init(Cipher.ENCRYPT_MODE, key); |
| byte[] endata = cipher.doFinal(msg.getBytes()); |
| return Base64.getEncoder().encodeToString(endata); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| throw new RuntimeException("加密失败"); |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| public static String aesDeCoding(String bs64Str) { |
| if(bs64Str == null) { |
| throw new RuntimeException("解密字符串不能为空"); |
| } |
| try { |
| Cipher cipher = Cipher.getInstance("AES"); |
| Key key = new SecretKeySpec(KEY.getBytes(), "AES"); |
| cipher.init(Cipher.DECRYPT_MODE, key); |
| byte[] code = Base64.getDecoder().decode(bs64Str); |
| byte[] dedata = cipher.doFinal(code); |
| return new String(dedata); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| throw new RuntimeException("加密失败"); |
| } |
| } |
| |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
2021-05-07 vue2.0入门