漯河网站建设兼职,做网站需要什么人,网站建设开发背景简介,北京建站系统模板简述
介绍其三种密码加密方法 1.SM2加密与验签 2.随机密码盐加密 3.MD5加密 推荐使用方法1#xff0c;其次使用方法2#xff0c;最不推荐的是方法3。方法3极其容易被密码字典破解#xff0c;如果项目进行安全测试#xff0c;通常是不允许的加密方式。
SM2加密与验签
引入…简述
介绍其三种密码加密方法 1.SM2加密与验签 2.随机密码盐加密 3.MD5加密 推荐使用方法1其次使用方法2最不推荐的是方法3。方法3极其容易被密码字典破解如果项目进行安全测试通常是不允许的加密方式。
SM2加密与验签
引入bcprov以使用SM2加密。 dependencygroupIdorg.bouncycastle/groupIdartifactIdbcprov-jdk15to18/artifactIdversion1.69/version/dependency工具类与测试方法
加密的主要工具类如下其中带有测试的main方法。
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECParameterSpec;import java.security.*;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.Map;/*** sm2算法与签名的使用** author fir* date 2024/7/23 14:22*/
Slf4j
public class Sm2SignatureUtils {static {Security.addProvider(new BouncyCastleProvider());}public static final String PUBLIC_KEY publicKey;public static final String PRIVATE_KEY privateKey;/*** 生成国密公私钥对*/public static MapString, String generateSmKey() throws Exception {KeyPairGenerator keyPairGenerator;SecureRandom secureRandom new SecureRandom();ECGenParameterSpec sm2Spec new ECGenParameterSpec(sm2p256v1);keyPairGenerator KeyPairGenerator.getInstance(EC, new BouncyCastleProvider());keyPairGenerator.initialize(sm2Spec);keyPairGenerator.initialize(sm2Spec, secureRandom);KeyPair keyPair keyPairGenerator.generateKeyPair();PrivateKey privateKey keyPair.getPrivate();PublicKey publicKey keyPair.getPublic();String publicKeyStr new String(Base64.getEncoder().encode(publicKey.getEncoded()));String privateKeyStr new String(Base64.getEncoder().encode(privateKey.getEncoded()));return Map.of(PUBLIC_KEY, publicKeyStr, PRIVATE_KEY, privateKeyStr);}/*** 将Base64转码的公钥串转化为公钥对象*/public static PublicKey createPublicKey(String publicKey) {PublicKey publickey null;try {X509EncodedKeySpec publicKeySpec new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey));KeyFactory keyFactory KeyFactory.getInstance(EC, new BouncyCastleProvider());publickey keyFactory.generatePublic(publicKeySpec);} catch (Exception e) {log.error(将Base64转码的公钥串转化为公钥对象异常{}, e.getMessage(), e);}return publickey;}/*** 将Base64转码的私钥串转化为私钥对象*/public static PrivateKey createPrivateKey(String privateKey) {PrivateKey publickey null;try {PKCS8EncodedKeySpec pkcs8EncodedKeySpec new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey));KeyFactory keyFactory KeyFactory.getInstance(EC, new BouncyCastleProvider());publickey keyFactory.generatePrivate(pkcs8EncodedKeySpec);} catch (Exception e) {log.error(将Base64转码的私钥串转化为私钥对象异常{}, e.getMessage(), e);}return publickey;}/*** 根据publicKey对原始数据data使用SM2加密*/public static String encrypt(byte[] data, String publicKeyBase64) {PublicKey publicKey createPublicKey(publicKeyBase64);ECPublicKeyParameters localEcPublicKeyParameters getEcPublicKeyParameters(publicKey);SM2Engine localSm2Engine new SM2Engine();localSm2Engine.init(true, new ParametersWithRandom(localEcPublicKeyParameters, new SecureRandom()));byte[] arrayOfByte2;try {arrayOfByte2 localSm2Engine.processBlock(data, 0, data.length);return Base64.getEncoder().encodeToString(arrayOfByte2);} catch (InvalidCipherTextException e) {log.error(SM2加密失败:{}, e.getMessage(), e);return null;}}private static ECPublicKeyParameters getEcPublicKeyParameters(PublicKey publicKey) {ECPublicKeyParameters localEcPublicKeyParameters null;if (publicKey instanceof BCECPublicKey localEcPublicKey) {ECParameterSpec localEcParameterSpec localEcPublicKey.getParameters();ECDomainParameters localEcDomainParameters new ECDomainParameters(localEcParameterSpec.getCurve(),localEcParameterSpec.getG(), localEcParameterSpec.getN());localEcPublicKeyParameters new ECPublicKeyParameters(localEcPublicKey.getQ(), localEcDomainParameters);}return localEcPublicKeyParameters;}/*** 根据privateKey对加密数据encode data使用SM2解密*/public static String decrypt(String encodeBase64, String privateKeyBase64) {SM2Engine localSm2Engine new SM2Engine();PrivateKey privateKey createPrivateKey(privateKeyBase64);BCECPrivateKey sm2PriK (BCECPrivateKey) privateKey;byte[] encodeData Base64.getDecoder().decode(encodeBase64);ECParameterSpec localEcParameterSpec sm2PriK.getParameters();ECDomainParameters localEcDomainParameters new ECDomainParameters(localEcParameterSpec.getCurve(),localEcParameterSpec.getG(), localEcParameterSpec.getN());ECPrivateKeyParameters localEcPrivateKeyParameters new ECPrivateKeyParameters(sm2PriK.getD(),localEcDomainParameters);localSm2Engine.init(false, localEcPrivateKeyParameters);try {byte[] result localSm2Engine.processBlock(encodeData, 0, encodeData.length);return new String(result);} catch (InvalidCipherTextException e) {log.error(SM2解密失败:{}, e.getMessage(), e);return null;}}/*** 私钥,数据,生成签名*/public static String signByPrivateKey(String dataStr, String privateKeyBase64) throws Exception {PrivateKey privateKey createPrivateKey(privateKeyBase64);byte[] data Base64.getDecoder().decode(dataStr);Signature sig Signature.getInstance(GMObjectIdentifiers.sm2sign_with_sm3.toString(), BouncyCastleProvider.PROVIDER_NAME);sig.initSign(privateKey);sig.update(data);byte[] sign sig.sign();return Base64.getEncoder().encodeToString(sign);}/*** 公钥与签名验证数据合法性*/public static boolean verifyByPublicKey(String dataStr, String publicKeyBase64, String signatureBase64) throws Exception {PublicKey publicKey createPublicKey(publicKeyBase64);byte[] signature Base64.getDecoder().decode(signatureBase64);byte[] data Base64.getDecoder().decode(dataStr);Signature sig Signature.getInstance(GMObjectIdentifiers.sm2sign_with_sm3.toString(), BouncyCastleProvider.PROVIDER_NAME);sig.initVerify(publicKey);sig.update(data);return sig.verify(signature);}public static void test() throws Exception {// 生成公私钥对MapString, String keys generateSmKey();String publicKey keys.get(PUBLIC_KEY);String privateKey keys.get(PRIVATE_KEY);String testStr 123456;System.out.println(原始字符串 testStr);System.out.println(公钥 keys.get(PUBLIC_KEY));System.out.println(私钥 keys.get(PRIVATE_KEY));System.out.println();// 公钥加密String encrypt encrypt(testStr.getBytes(), publicKey);System.out.println(加密数据 encrypt);// 私钥签名,后续根据数据与公钥验签String sign signByPrivateKey(encrypt, privateKey);System.out.println(数据签名 sign);// 公钥验签验证通过后再进行数据解密boolean b verifyByPublicKey(encrypt, publicKey, sign);System.out.println(数据验签 b);//私钥解密String decrypt decrypt(encrypt, privateKey);System.out.println(解密数据 decrypt);}public static void uesCase() throws Exception {//生成公私钥对String publicKey MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEsrdE0XrAO2S7Ize0tm0r3diH9cPH23t0J9yVDtiVux6g71msH5YGTWW6/ogQSCVJ4iaofgCS/ly5wkXa/IGg;String privateKey MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgNxbJcu1vhGt9UEbeFUYeCCRWL7sfUL1vnhBp2KtKgCgYIKoEcz1UBgi2hRANCAASyt0TResA7ZLsjN7S2bSvd2If1w8fbe3Qn3JUO2JW7HqDvWawflgZNZbriBBIJUniJqhAJLXLn7CRdr78ga;String testStr 123456;System.out.println(原始字符串 testStr);System.out.println(公钥 publicKey);System.out.println(私钥 privateKey);System.out.println();//公钥加密String encrypt encrypt(testStr.getBytes(), publicKey);System.out.println(加密数据 encrypt);// 私钥签名,后续根据数据与公钥验签String sign signByPrivateKey(encrypt, privateKey);System.out.println(数据签名 sign);//公钥验签验证通过后再进行数据解密boolean b verifyByPublicKey(encrypt, publicKey, sign);System.out.println(数据验签 b);//私钥解密String decrypt decrypt(encrypt, privateKey);System.out.println(解密数据 decrypt);}public static void main(String[] args) {try {test();
// uesCase();} catch (Exception e) {throw new RuntimeException(e);}}
}
使用案例
验证密码
接受到用户输入的用户与密码之后在数据库中查询出旧的密码并进行旧密码进行验签、解密。解密后判断用户输入的密码与数据库存储的密码是否相同。 // 验证密码是否正确String password 123456;String passwordOld user.getPassword();String signature user.getSignature();String decryptPasswordOld null;try {// 公钥验签查看数据与签名是否有效boolean b Sm2SignatureUtils.verifyByPublicKey(passwordOld, public, signature);if(!b){throw new CommonException(数据损坏);}decryptPasswordOld Sm2SignatureUtils.decrypt(passwordOld, private);}catch (Exception e){throw new CommonException(数据损坏);}if (decryptPasswordOld null || !decryptPasswordOld.equals(password)) {throw new CommonException(用户密码错误);}修改密码
接收到用户的密码后根据公私要生成加密数据串与私钥签名。并存储到数据库用于之后的密码验证。 // 公钥加密String password 123456;String encrypt Sm2SignatureUtils.encrypt(password.getBytes(), public);// 根据数据与私钥生成私钥签名String sign Sm2SignatureUtils.signByPrivateKey(encrypt, private);user.setPassword(encrypt);user.setSignature(sign);随机密码盐加密
工具类与测试方法
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;/*** author fir* date 2024/7/25 12:22*/
public class SaltUtils {/*** 生成随机安全盐** return 盐*/public static String generateSalt() {// 使用SecureRandom生成安全的随机盐SecureRandom random new SecureRandom();byte[] salt new byte[16];random.nextBytes(salt);return Base64.getEncoder().encodeToString(salt);}/*** 生成加盐密码** return 盐*/public static String hashPassword(String password, String salt){// 将密码和盐结合String saltedPassword password salt;// 使用SHA-256进行哈希MessageDigest md;try {md MessageDigest.getInstance(SHA-256);}catch (NoSuchAlgorithmException e){throw new RuntimeException(加密盐处理失败);}byte[] hashedBytes md.digest(saltedPassword.getBytes());// 将哈希值转换为字符串return Base64.getEncoder().encodeToString(hashedBytes);}public static void main(String[] args){String salt generateSalt();String password 123456;String hashPassword hashPassword(password, salt);System.out.println(盐: salt);System.out.println(密码: password);System.out.println(加密密码: hashPassword);}}
使用案例
验证密码
查询出用户的密码将用户输入的密码盐加密并判断与数据库的加密密码是否一致。 String password 123456;String salt user.getSalt();String passwordOld user.getPassword();String mPassword SaltUtils.hashPassword(password, salt);if (!mPassword.equals(passwordOld)) {throw new CommonException(密码错误);}修改密码
将用户输入的密码md5加密之后存在数据库中用于之后的密码验证 String password 123456;String salt SaltUtils.generateSalt();String hashPassword SaltUtils.hashPassword(password, salt);user.setPassword(hashPassword);MD5加密
引入hutool包以使用md5加密。 dependencygroupIdcn.hutool/groupIdartifactIdhutool-all/artifactIdversion5.8.19/version/dependency测试方法
import cn.hutool.crypto.digest.MD5;/*** author fir* date 2024/7/22 10:07*/
public class Md5Utils {public static void main(String[] args){// MD5取值String mPassword MD5.create().digestHex(123456);System.out.println(mPassword);}
}
使用案例
验证密码
查询出用户的密码将用户输入的密码MD5加密并判断与数据库的加密密码是否一致。 String password 123456;String mPassword MD5.create().digestHex(password);String passwordOld user.getPassword();if (!mPassword.equals(passwordOld)) {throw new CommonException(密码错误);}修改密码
将用户输入的密码md5加密之后存在数据库中用于之后的密码验证 String password 123456;String passwordMd5 MD5.create().digestHex(password);user.setPassword(passwordMd5);