java SM2解密


SM2Utils里面标注了,需要改成自己的密钥,记得修改,测试方法在SM2Utils里面。

1、引入Maven库

<dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.54</version>
        </dependency>

2、密码工具类

package com.ruoyi.web.controller.tool.util;

import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.math.ec.ECPoint;

import java.math.BigInteger;

public class Cipher
{
    private int ct;
    private ECPoint p2;
    private SM3Digest sm3keybase;
    private SM3Digest sm3c3;
    private byte[] key;
    private byte keyOff;

    public Cipher()
    {
        this.ct = 1;
        this.key = new byte[32];
        this.keyOff = 0;
    }

    private void Reset() {
        this.sm3keybase = new SM3Digest();
        this.sm3c3 = new SM3Digest();

        byte[] p = Util.byteConvert32Bytes(this.p2.getX().toBigInteger());
        this.sm3keybase.update(p, 0, p.length);
        this.sm3c3.update(p, 0, p.length);

        p = Util.byteConvert32Bytes(this.p2.getY().toBigInteger());
        this.sm3keybase.update(p, 0, p.length);
        this.ct = 1;
        NextKey();
    }

    private void NextKey() {
        SM3Digest sm3keycur = new SM3Digest(this.sm3keybase);
        sm3keycur.update((byte)(this.ct >> 24 & 0xFF));
        sm3keycur.update((byte)(this.ct >> 16 & 0xFF));
        sm3keycur.update((byte)(this.ct >> 8 & 0xFF));
        sm3keycur.update((byte)(this.ct & 0xFF));
        sm3keycur.doFinal(this.key, 0);
        this.keyOff = 0;
        this.ct += 1;
    }

    public ECPoint Init_enc(SM2 sm2, ECPoint userKey) {
        AsymmetricCipherKeyPair key = sm2.ecc_key_pair_generator.generateKeyPair();
        ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters)key.getPrivate();
        ECPublicKeyParameters ecpub = (ECPublicKeyParameters)key.getPublic();
        BigInteger k = ecpriv.getD();
        ECPoint c1 = ecpub.getQ();
        this.p2 = userKey.multiply(k);
        Reset();
        return c1;
    }

    public void Encrypt(byte[] data) {
        this.sm3c3.update(data, 0, data.length);
        for (int i = 0; i < data.length; ++i) {
            if (this.keyOff == this.key.length)
                NextKey();
            int tmp37_36 = i;
            byte[] tmp37_35 = data;
            Cipher tmp44_43 = this;
            byte tmp48_45 = tmp44_43.keyOff; tmp44_43.keyOff = (byte)(tmp48_45 + 1); tmp37_35[tmp37_36] = (byte)(tmp37_35[tmp37_36] ^ this.key[tmp48_45]);
        }
    }

    public void Init_dec(BigInteger userD, ECPoint c1) {
        this.p2 = c1.multiply(userD);
        Reset();
    }

    public void Decrypt(byte[] data) {
        for (int i = 0; i < data.length; ++i) {
            if (this.keyOff == this.key.length)
                NextKey();
            int tmp26_25 = i;
            byte[] tmp26_24 = data;
            Cipher tmp33_32 = this;
            byte tmp37_34 = tmp33_32.keyOff; tmp33_32.keyOff = (byte)(tmp37_34 + 1); tmp26_24[tmp26_25] = (byte)(tmp26_24[tmp26_25] ^ this.key[tmp37_34]);
        }
        this.sm3c3.update(data, 0, data.length);
    }

    public void Dofinal(byte[] c3) {
        byte[] p = Util.byteConvert32Bytes(this.p2.getY().toBigInteger());
        this.sm3c3.update(p, 0, p.length);
        this.sm3c3.doFinal(c3, 0);
        Reset();
    }
}

3、安全工具类

package com.ruoyi.web.controller.tool.util;

import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECCurve.Fp;
import org.bouncycastle.math.ec.ECFieldElement;
import org.bouncycastle.math.ec.ECPoint;

import java.math.BigInteger;
import java.security.SecureRandom;

public class SM2
{
    public static String[] ecc_param = { "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0" };
    public final BigInteger ecc_p;
    public final BigInteger ecc_a;
    public final BigInteger ecc_b;
    public final BigInteger ecc_n;
    public final BigInteger ecc_gx;
    public final BigInteger ecc_gy;
    public final ECCurve ecc_curve;
    public final ECPoint ecc_point_g;
    public final ECDomainParameters ecc_bc_spec;
    public final ECKeyPairGenerator ecc_key_pair_generator;
    public final ECFieldElement ecc_gx_fieldelement;
    public final ECFieldElement ecc_gy_fieldelement;

    public static SM2 Instance()
    {
        return new SM2();
    }

    public SM2()
    {
        this.ecc_p = new BigInteger(ecc_param[0], 16);
        this.ecc_a = new BigInteger(ecc_param[1], 16);
        this.ecc_b = new BigInteger(ecc_param[2], 16);
        this.ecc_n = new BigInteger(ecc_param[3], 16);
        this.ecc_gx = new BigInteger(ecc_param[4], 16);
        this.ecc_gy = new BigInteger(ecc_param[5], 16);

        this.ecc_gx_fieldelement = new ECFieldElement.Fp(this.ecc_p, this.ecc_gx);
        this.ecc_gy_fieldelement = new ECFieldElement.Fp(this.ecc_p, this.ecc_gy);

        this.ecc_curve = new Fp(this.ecc_p, this.ecc_a, this.ecc_b);
        this.ecc_point_g = new ECPoint.Fp(this.ecc_curve, this.ecc_gx_fieldelement, this.ecc_gy_fieldelement);

        this.ecc_bc_spec = new ECDomainParameters(this.ecc_curve, this.ecc_point_g, this.ecc_n);

        ECKeyGenerationParameters ecc_ecgenparam = new ECKeyGenerationParameters(this.ecc_bc_spec, new SecureRandom());

        this.ecc_key_pair_generator = new ECKeyPairGenerator();
        this.ecc_key_pair_generator.init(ecc_ecgenparam);
    }
}

4.SM2工具类

将下面的密钥改成自己的

package com.ruoyi.web.controller.tool.util;

import org.bouncycastle.math.ec.ECPoint;

import java.io.IOException;
import java.math.BigInteger;

public class SM2Utils
{
    public static byte[] decrypt(String data0)
    {
        try
        {
            byte[] encryptedData = Util.hexToByte(data0);
            if ((encryptedData == null) || (encryptedData.length == 0)) {
                return null;
            }

            String data = Util.byteToHex(encryptedData);

            byte[] c1Bytes = Util.hexToByte(data.substring(0, 130));
            int c2Len = encryptedData.length - 97;
            byte[] c2 = Util.hexToByte(data.substring(130, 130 + 2 * c2Len));
            byte[] c3 = Util.hexToByte(data.substring(130 + 2 * c2Len, 194 + 2 * c2Len));

            SM2 sm2 = new SM2();
            //TODO 改自己的密钥
            BigInteger userD = new BigInteger(1, Util.hexToByte("自己的密钥"));

            ECPoint c1 = sm2.ecc_curve.decodePoint(c1Bytes);
            Cipher cipher = new Cipher();
            cipher.Init_dec(userD, c1);
            cipher.Decrypt(c2);
            cipher.Dofinal(c3);
            return c2;
        } catch (Exception e) {
            e.printStackTrace();
            System.out.print("时间:" + System.currentTimeMillis() + "解密失败:" + e.getMessage()); }
        return null;
    }

    public static void main(String[] args)
            throws IOException
    {
        byte[] decrypt = decrypt("加密信息");

        String newInfo = new String(decrypt, "utf-8");
        System.out.println("解密后信息:" + newInfo);
    }
}

5、Utils类
package com.ruoyi.web.controller.tool.util;


import java.math.BigInteger;

public class Util
{
    private static final char[] DIGITS_LOWER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

    private static final char[] DIGITS_UPPER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

    public static byte[] intToBytes(int num)
    {
        byte[] bytes = new byte[4];
        bytes[0] = (byte)(0xFF & num >> 0);
        bytes[1] = (byte)(0xFF & num >> 8);
        bytes[2] = (byte)(0xFF & num >> 16);
        bytes[3] = (byte)(0xFF & num >> 24);
        return bytes;
    }

    public static int byteToInt(byte[] bytes)
    {
        int num = 0;

        int temp = (0xFF & bytes[0]) << 0;
        num |= temp;
        temp = (0xFF & bytes[1]) << 8;
        num |= temp;
        temp = (0xFF & bytes[2]) << 16;
        num |= temp;
        temp = (0xFF & bytes[3]) << 24;
        num |= temp;
        return num;
    }

    public static byte[] longToBytes(long num)
    {
        byte[] bytes = new byte[8];
        for (int i = 0; i < 8; ++i) {
            bytes[i] = (byte)(int)(0xFF & num >> i * 8);
        }

        return bytes;
    }

    public static byte[] byteConvert32Bytes(BigInteger n)
    {
        byte[] tmpd = (byte[])null;
        if (n == null) {
            return null;
        }

        if (n.toByteArray().length == 33) {
            tmpd = new byte[32];
            System.arraycopy(n.toByteArray(), 1, tmpd, 0, 32);
        }
        else if (n.toByteArray().length == 32) {
            tmpd = n.toByteArray();
        }
        else {
            tmpd = new byte[32];
            for (int i = 0; i < 32 - n.toByteArray().length; ++i) {
                tmpd[i] = 0;
            }
            System.arraycopy(n.toByteArray(), 0, tmpd, 32 - n.toByteArray().length, n.toByteArray().length);
        }
        return tmpd;
    }

    public static BigInteger byteConvertInteger(byte[] b)
    {
        if (b[0] < 0) {
            byte[] temp = new byte[b.length + 1];
            temp[0] = 0;
            System.arraycopy(b, 0, temp, 1, b.length);
            return new BigInteger(temp);
        }
        return new BigInteger(b);
    }

    public static String getHexString(byte[] bytes)
    {
        return getHexString(bytes, true);
    }

    public static String getHexString(byte[] bytes, boolean upperCase)
    {
        String ret = "";
        for (int i = 0; i < bytes.length; ++i) {
            ret = ret + Integer.toString((bytes[i] & 0xFF) + 256, 16).substring(1);
        }
        return ((upperCase) ? ret.toUpperCase() : ret);
    }

    public static void printHexString(byte[] bytes)
    {
        for (int i = 0; i < bytes.length; ++i) {
            String hex = Integer.toHexString(bytes[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            System.out.print("0x" + hex.toUpperCase() + ",");
        }
        System.out.println("");
    }

    public static byte[] hexStringToBytes(String hexString)
    {
        if ((hexString == null) || (hexString.equals(""))) {
            return null;
        }

        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; ++i) {
            int pos = i * 2;
            d[i] = (byte)(charToByte(hexChars[pos]) << 4 | charToByte(hexChars[(pos + 1)]));
        }
        return d;
    }

    public static byte charToByte(char c)
    {
        return (byte)"0123456789ABCDEF".indexOf(c);
    }

    public static char[] encodeHex(byte[] data)
    {
        return encodeHex(data, true);
    }

    public static char[] encodeHex(byte[] data, boolean toLowerCase)
    {
        return encodeHex(data, (toLowerCase) ? DIGITS_LOWER : DIGITS_UPPER);
    }

    protected static char[] encodeHex(byte[] data, char[] toDigits)
    {
        int l = data.length;
        char[] out = new char[l << 1];

        int i = 0; for (int j = 0; i < l; ++i) {
        out[(j++)] = toDigits[((0xF0 & data[i]) >>> 4)];
        out[(j++)] = toDigits[(0xF & data[i])];
    }
        return out;
    }

    public static String encodeHexString(byte[] data)
    {
        return encodeHexString(data, true);
    }

    public static String encodeHexString(byte[] data, boolean toLowerCase)
    {
        return encodeHexString(data, (toLowerCase) ? DIGITS_LOWER : DIGITS_UPPER);
    }

    protected static String encodeHexString(byte[] data, char[] toDigits)
    {
        return new String(encodeHex(data, toDigits));
    }

    public static byte[] decodeHex(char[] data)
    {
        int len = data.length;

        if ((len & 0x1) != 0) {
            throw new RuntimeException("Odd number of characters.");
        }

        byte[] out = new byte[len >> 1];

        int i = 0; for (int j = 0; j < len; ++i) {
        int f = toDigit(data[j], j) << 4;
        ++j;
        f |= toDigit(data[j], j);
        ++j;
        out[i] = (byte)(f & 0xFF);
    }

        return out;
    }

    protected static int toDigit(char ch, int index)
    {
        int digit = Character.digit(ch, 16);
        if (digit == -1) {
            throw new RuntimeException("Illegal hexadecimal character " + ch + " at index " + index);
        }

        return digit;
    }

    public static String StringToAsciiString(String content)
    {
        String result = "";
        int max = content.length();
        for (int i = 0; i < max; ++i) {
            char c = content.charAt(i);
            String b = Integer.toHexString(c);
            result = result + b;
        }
        return result;
    }

    public static String hexStringToString(String hexString, int encodeType)
    {
        String result = "";
        int max = hexString.length() / encodeType;
        for (int i = 0; i < max; ++i) {
            char c = (char)hexStringToAlgorism(hexString
                    .substring(i * encodeType, (i + 1) * encodeType));

            result = result + c;
        }
        return result;
    }

    public static int hexStringToAlgorism(String hex)
    {
        hex = hex.toUpperCase();
        int max = hex.length();
        int result = 0;
        for (int i = max; i > 0; --i) {
            char c = hex.charAt(i - 1);
            int algorism = 0;
            if ((c >= '0') && (c <= '9'))
                algorism = c - '0';
            else {
                algorism = c - '7';
            }
            result = (int)(result + Math.pow(16.0D, max - i) * algorism);
        }
        return result;
    }

    public static String hexStringToBinary(String hex)
    {
        hex = hex.toUpperCase();
        String result = "";
        int max = hex.length();
        for (int i = 0; i < max; ++i) {
            char c = hex.charAt(i);
            switch (c) { case '0':
                result = result + "0000";
                break;
                case '1':
                    result = result + "0001";
                    break;
                case '2':
                    result = result + "0010";
                    break;
                case '3':
                    result = result + "0011";
                    break;
                case '4':
                    result = result + "0100";
                    break;
                case '5':
                    result = result + "0101";
                    break;
                case '6':
                    result = result + "0110";
                    break;
                case '7':
                    result = result + "0111";
                    break;
                case '8':
                    result = result + "1000";
                    break;
                case '9':
                    result = result + "1001";
                    break;
                case 'A':
                    result = result + "1010";
                    break;
                case 'B':
                    result = result + "1011";
                    break;
                case 'C':
                    result = result + "1100";
                    break;
                case 'D':
                    result = result + "1101";
                    break;
                case 'E':
                    result = result + "1110";
                    break;
                case 'F':
                    result = result + "1111";
                case ':':
                case ';':
                case '<':
                case '=':
                case '>':
                case '?':
                case '@': }  } return result;
    }

    public static String AsciiStringToString(String content)
    {
        String result = "";
        int length = content.length() / 2;
        for (int i = 0; i < length; ++i) {
            String c = content.substring(i * 2, i * 2 + 2);
            int a = hexStringToAlgorism(c);
            char b = (char)a;
            String d = String.valueOf(b);
            result = result + d;
        }
        return result;
    }

    public static String algorismToHexString(int algorism, int maxLength)
    {
        String result = "";
        result = Integer.toHexString(algorism);

        if (result.length() % 2 == 1) {
            result = "0" + result;
        }
        return patchHexString(result.toUpperCase(), maxLength);
    }

    public static String byteToString(byte[] bytearray)
    {
        String result = "";

        int length = bytearray.length;
        for (int i = 0; i < length; ++i) {
            char temp = (char)bytearray[i];
            result = result + temp;
        }
        return result;
    }

    public static int binaryToAlgorism(String binary)
    {
        int max = binary.length();
        int result = 0;
        for (int i = max; i > 0; --i) {
            char c = binary.charAt(i - 1);
            int algorism = c - '0';
            result = (int)(result + Math.pow(2.0D, max - i) * algorism);
        }
        return result;
    }

    public static String algorismToHEXString(int algorism)
    {
        String result = "";
        result = Integer.toHexString(algorism);

        if (result.length() % 2 == 1) {
            result = "0" + result;
        }

        result = result.toUpperCase();

        return result;
    }

    public static String patchHexString(String str, int maxLength)
    {
        String temp = "";
        for (int i = 0; i < maxLength - str.length(); ++i) {
            temp = "0" + temp;
        }
        str = temp + str.substring(0, maxLength);
        return str;
    }

    public static int parseToInt(String s, int defaultInt, int radix)
    {
        int i = 0;
        try {
            i = Integer.parseInt(s, radix);
        } catch (NumberFormatException ex) {
            i = defaultInt;
        }
        return i;
    }

    public static int parseToInt(String s, int defaultInt)
    {
        int i = 0;
        try {
            i = Integer.parseInt(s);
        } catch (NumberFormatException ex) {
            i = defaultInt;
        }
        return i;
    }

    public static byte[] hexToByte(String hex)
            throws IllegalArgumentException
    {
        if (hex.length() % 2 != 0) {
            throw new IllegalArgumentException();
        }
        char[] arr = hex.toCharArray();
        byte[] b = new byte[hex.length() / 2];
        int i = 0; int j = 0; for (int l = hex.length(); i < l; ++j) {
        String swap = "" + arr[(i++)] + arr[i];
        int byteint = Integer.parseInt(swap, 16) & 0xFF;
        b[j] = new Integer(byteint).byteValue();

        ++i;
    }

        return b;
    }

    public static String byteToHex(byte[] b)
    {
        if (b == null) {
            throw new IllegalArgumentException("Argument b ( byte array ) is null! ");
        }

        String hs = "";
        String stmp = "";
        for (int n = 0; n < b.length; ++n) {
            stmp = Integer.toHexString(b[n] & 0xFF);
            if (stmp.length() == 1)
                hs = hs + "0" + stmp;
            else {
                hs = hs + stmp;
            }
        }
        return hs.toUpperCase();
    }

    public static byte[] subByte(byte[] input, int startIndex, int length) {
        byte[] bt = new byte[length];
        for (int i = 0; i < length; ++i) {
            bt[i] = input[(i + startIndex)];
        }
        return bt;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值