java 报错 Cipher not initialized

老代码中,进行对称加密解密的时候报这个错误,老代码写的不够清晰可能在并发的时候报此错误.

老代码:

package co.yixiang.utils;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.symmetric.DES;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import org.springframework.util.DigestUtils;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.nio.charset.StandardCharsets;

/**
 * 加密
 * @author Zheng Jie
 * @date 2018-11-23
 */
public class EncryptUtils {

    private static String strParam = "Passw0rd";

    private static Cipher cipher;

    private static IvParameterSpec iv = new IvParameterSpec(strParam.getBytes(StandardCharsets.UTF_8));

    private static DESKeySpec getDesKeySpec(String source) throws Exception {
        if (source == null || source.length() == 0){
            return null;
        }
        cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        String strKey = "Passw0rd";
        return new DESKeySpec(strKey.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 新版本的对称加密
     * @param source
     * @return
     * @throws Exception
     */
    public static String desEncrypt(String source) throws Exception {
        DES des = new DES(Mode.CTS, Padding.PKCS5Padding, strParam.getBytes(), strParam.getBytes());
        //加密为16进制表示
        String encryptHex = des.encryptHex(source);
        return encryptHex.toUpperCase();
    }
    /**
     * 新版本的对称解密
     * @param source
     * @return
     * @throws Exception
     */
    public static String desDecrypt(String source) throws Exception {
        DES des = new DES(Mode.CTS, Padding.PKCS5Padding, strParam.getBytes(), strParam.getBytes());
        //解密为字符串
        String decryptStr = des.decryptStr(source, CharsetUtil.CHARSET_UTF_8);
        return decryptStr;
    }


    /**
     * 对称加密
     */
    /*public static String desEncrypt(String source) throws Exception {
        DESKeySpec desKeySpec = getDesKeySpec(source);
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
        return byte2hex(
                cipher.doFinal(source.getBytes(StandardCharsets.UTF_8))).toUpperCase();
    }*/

    /**
     * 对称解密
     */
   /* public static String desDecrypt(String source) throws Exception {
        byte[] src = hex2byte(source.getBytes());
        DESKeySpec desKeySpec = getDesKeySpec(source);
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
        cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
        byte[] retByte = cipher.doFinal(src);
        return new String(retByte);
    }*/

    private static String byte2hex(byte[] inStr) {
        String stmp;
        StringBuilder out = new StringBuilder(inStr.length * 2);
        for (byte b : inStr) {
            stmp = Integer.toHexString(b & 0xFF);
            if (stmp.length() == 1) {
                // 如果是0至F的单位字符串,则添加0
                out.append("0").append(stmp);
            } else {
                out.append(stmp);
            }
        }
        return out.toString();
    }

    private static byte[] hex2byte(byte[] b) {
        int size = 2;
        if ((b.length % size) != 0){
            throw new IllegalArgumentException("长度不是偶数");
        }
        byte[] b2 = new byte[b.length / 2];
        for (int n = 0; n < b.length; n += size) {
            String item = new String(b, n, 2);
            b2[n / 2] = (byte) Integer.parseInt(item, 16);
        }
        return b2;
    }

    /**
     * 密码加密
     * @param password
     * @return
     */
    public static String encryptPassword(String password){
        return  DigestUtils.md5DigestAsHex(password.getBytes());
    }
}

其中 注释 对称加密和对称解密的两个方法为老版代码,

新版本的对称加密和新版本的对称解密为新版本的代码,

新版本加密解密使用hutool库,需要引入依赖

替换后,线上没有在出现此异常

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中的SM2Cipher是一种实现SM2椭圆曲线加密算法的类。SM2是一种国密标准,用于数字签名和加密。以下是一个简单的SM2Cipher类示例: ```java import org.bouncycastle.crypto.engines.SM2Engine; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.util.PrivateKeyFactory; import org.bouncycastle.crypto.util.PublicKeyFactory; import org.bouncycastle.math.ec.ECPoint; import java.security.SecureRandom; public class SM2Cipher { private byte[] publicKey; private byte[] privateKey; private SecureRandom random; public SM2Cipher() { random = new SecureRandom(); } public void setPublicKey(byte[] publicKey) { this.publicKey = publicKey; } public void setPrivateKey(byte[] privateKey) { this.privateKey = privateKey; } public byte[] encrypt(byte[] data) { try { ECPublicKeyParameters publicKeyParam = (ECPublicKeyParameters) PublicKeyFactory.createKey(publicKey); ParametersWithRandom params = new ParametersWithRandom(publicKeyParam, random); SM2Engine engine = new SM2Engine(); engine.init(true, params); return engine.processBlock(data, 0, data.length); } catch (Exception e) { e.printStackTrace(); return null; } } public byte[] decrypt(byte[] data) { try { ECPrivateKeyParameters privateKeyParam = (ECPrivateKeyParameters) PrivateKeyFactory.createKey(privateKey); SM2Engine engine = new SM2Engine(); engine.init(false, privateKeyParam); return engine.processBlock(data, 0, data.length); } catch (Exception e) { e.printStackTrace(); return null; } } public ECPoint createPoint(String xHex, String yHex) { return SM2Util.createPoint(xHex, yHex); } } ``` 在这个例子中,SM2Cipher类提供了加密和解密方法,以及创建椭圆曲线点的方法。它使用bouncycastle库来实现SM2算法。加密和解密方法都需要设置公钥和私钥,这里只提供了简单的字节数组设置方法。createPoint方法使用SM2Util类来创建椭圆曲线点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值