方式1:前端不加密 + 后端加密
目的:后端不直接存储密码明文。
1)注册:后端接收前端传输的密码明文后,使用不可逆的加密(如hash)对其加密后存入数据库;
2)登录:后端接收前端传输的密码明文后,将密码与数据库中密文进行对比验证(验证方法据实际加密方式而定)。
示例:
java后端加密:
import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class HashUtil { public static String hash(String password) { try { // 创建MessageDigest对象,指定使用MD5算法 MessageDigest md = MessageDigest.getInstance("MD5"); // 将密码转换为byte数组 byte[] passwordBytes = password.getBytes(); // 使用指定的byte数组更新摘要 md.update(passwordBytes); // 获取摘要的字节数组 byte[] digest = md.digest(); // 将字节数组转换为十六进制字符串 StringBuilder sb = new StringBuilder(); for (byte b : digest) { sb.append(String.format("%02x", b)); } return sb.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return null; } public static boolean verify(String password, String hashedPassword) { // 对输入的密码进行加密 String encryptedPassword = hash(password); // 验证加密后的密码与哈希值是否相等 return hashedPassword.equals(encryptedPassword); } public static void main(String[] args) { String password = "password"; // 对密码进行哈希加密 String hashedPassword = hash(password); System.out.println("哈希值:" + hashedPassword); // 验证密码 boolean result = verify(password, hashedPassword); System.out.println("验证结果:" + result); } }
方式2:前端加密 + 后端加密
目的:前端密码传输不直接暴露密码明文,后端不直接存储密码明文
1)注册:前端使用可解密的加密算法加密密码明文,后端拿到加密后的密码密文并解密,然后对其进行不可逆的加密(如hash)后存入数据库;
2)登录:前端使用可解密的加密算法加密密码明文,后端拿到加密后的密码密文并解密,将解密后的密码与数据库中密文进行对比验证(验证方法据实际加密方式而定)。
示例:示例只展示前端加密,后端解密过程,后端加密参照方式1。
前端加密:// 密钥,需要与后端保持一致 var key = CryptoJS.enc.Utf8.parse("1234567890123456"); // 加密函数 function encryptParam(param) { var encrypted = CryptoJS.AES.encrypt(JSON.stringify(param), key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }); return encrypted.toString(); } // 请求参数 var param = { username: "admin", password: "123456" }; // 加密请求参数 var encryptedParam = encryptParam(param); // 发送加密后的参数到后端 // ...
java后端解密:import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; public class AESUtil { private static final String KEY = "1234567890123456"; // 密钥,需要与前端保持一致 public static String decrypt(String encryptedParam) { try { byte[] encryptedBytes = Base64.getDecoder().decode(encryptedParam); SecretKeySpec secretKeySpec = new SecretKeySpec(KEY.getBytes(), "AES"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec); byte[] decryptedBytes = cipher.doFinal(encryptedBytes); return new String(decryptedBytes); } catch (Exception e) { e.printStackTrace(); return null; } } }
注:本文只记录前后端密码加解密逻辑及方式,不讨论安全性问题,纯菜鸡呜呜呜。