java sm2实现

来源:互联网 发布:cnc编程培训班苏州市 编辑:程序博客网 时间:2024/05/21 10:56
SM2  java代码的实现。
public class SM2 {    //正式参数    public static String[] ecc_param = {            "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF",            "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC",            "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93",            "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123",            "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7",            "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0"    };    private static SM2 instance;    private BigInteger ecc_p;    private BigInteger ecc_a;    private BigInteger ecc_b;    private BigInteger ecc_n;    private BigInteger ecc_gx;    private BigInteger ecc_gy;    private ECCurve.Fp ecc_curve;    private ECPoint.Fp ecc_point_g;    private ECDomainParameters ecc_bc_spec;    private ECKeyPairGenerator ecc_key_pair_generator;    private ECFieldElement ecc_gx_fieldelement;    private ECFieldElement ecc_gy_fieldelement;    private BigInteger privateKey;    private ECPoint publicKey;    private 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);        ecc_gx_fieldelement = new Fp(this.ecc_p, this.ecc_gx);        ecc_gy_fieldelement = new Fp(this.ecc_p, this.ecc_gy);        ecc_curve = new ECCurve.Fp(this.ecc_p, this.ecc_a, this.ecc_b);        ecc_point_g = new ECPoint.Fp(this.ecc_curve, this.ecc_gx_fieldelement, this.ecc_gy_fieldelement);        ecc_bc_spec = new ECDomainParameters(this.ecc_curve, this.ecc_point_g, this.ecc_n);        ECKeyGenerationParameters ecc_ecgenparam;        ecc_ecgenparam = new ECKeyGenerationParameters(ecc_bc_spec, new SecureRandom());        ecc_key_pair_generator = new ECKeyPairGenerator();        ecc_key_pair_generator.init(ecc_ecgenparam);        AsymmetricCipherKeyPair key = ecc_key_pair_generator.generateKeyPair();        ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters) key.getPrivate();        ECPublicKeyParameters ecpub = (ECPublicKeyParameters) key.getPublic();        privateKey = ecpriv.getD();        publicKey = ecpub.getQ();    }    public static SM2 getInstance() {        if (instance == null) {            synchronized (SM2.class) {                if (instance == null) {                    instance = new SM2();                }            }        }        return instance;    }    //数据加密    public String encrypt(byte[] data) throws IOException {        byte[] source = new byte[data.length];        System.arraycopy(data, 0, source, 0, data.length);        CipherUtil cipher = new CipherUtil();//        ECPoint userKey = ecc_curve.decodePoint(publicKey);        ECPoint c1 = cipher.Init_enc(ecc_key_pair_generator, publicKey);   //userKey        cipher.Encrypt(source);        byte[] c3 = new byte[32];        cipher.Dofinal(c3);//      System.out.println("C1 " + StrUtil.byteToHex(c1.getEncoded()));//      System.out.println("C2 " + StrUtil.byteToHex(source));//      System.out.println("C3 " + StrUtil.byteToHex(c3));        //C1 C2 C3拼装成加密字串        byte[] result = new byte[c1.getEncoded().length + source.length + c3.length];        return StrUtil.byteToHex(c1.getEncoded()) + StrUtil.byteToHex(source) + StrUtil.byteToHex(c3);    }    //数据加密    public byte[] encryptByte(byte[] data) throws IOException {        byte[] source = new byte[data.length];        System.arraycopy(data, 0, source, 0, data.length);        CipherUtil cipher = new CipherUtil();//        ECPoint userKey = ecc_curve.decodePoint(publicKey);        ECPoint c1 = cipher.Init_enc(ecc_key_pair_generator, publicKey);   //userKey        cipher.Encrypt(source);        byte[] c3 = new byte[32];        cipher.Dofinal(c3);//      System.out.println("C1 " + StrUtil.byteToHex(c1.getEncoded()));//      System.out.println("C2 " + StrUtil.byteToHex(source));//      System.out.println("C3 " + StrUtil.byteToHex(c3));        //C1 C2 C3拼装成加密字串        byte[] result = new byte[c1.getEncoded().length + source.length + c3.length];        System.arraycopy(c1.getEncoded(), 0, result, 0, c1.getEncoded().length);        System.arraycopy(source, 0, result, c1.getEncoded().length, source.length);        System.arraycopy(c3, 0, result, c1.getEncoded().length + source.length, c3.length);        return result;    }    //数据解密    public byte[] decrypt(byte[] encryptedData) throws IOException {        //加密字节数组转换为十六进制的字符串 长度变为encryptedData.length * 2        String data = StrUtil.byteToHex(encryptedData);        /***分解加密字串         * (C1 = C1标志位2位 + C1实体部分128位 = 130)         * (C3 = C3实体部分64位  = 64)         * (C2 = encryptedData.length * 2 - C1长度  - C2长度)         */        byte[] c1Bytes = StrUtil.hexToByte(data.substring(0, 130));        int c2Len = encryptedData.length - 97;        byte[] c2 = StrUtil.hexToByte(data.substring(130, 130 + 2 * c2Len));        byte[] c3 = StrUtil.hexToByte(data.substring(130 + 2 * c2Len, 194 + 2 * c2Len));        // BigInteger userD = new BigInteger(1, privateKey);        //通过C1实体字节来生成ECPoint        ECPoint c1 = ecc_curve.decodePoint(c1Bytes);        CipherUtil cipher = new CipherUtil();        cipher.Init_dec(privateKey, c1);   //userKey        cipher.Decrypt(c2);        cipher.Dofinal(c3);        //返回解密结果        return c2;    }    public String Sm2Sign(byte[] md) {        byte[] pk = publicKey.getEncoded();        byte[] prk = privateKey.toByteArray();        SM3Digest sm3 = new SM3Digest();        byte[] pkX = SubByte(pk, 0, 32);        byte[] pkY = SubByte(pk, 32, 32);        byte[] z = sm3.getSM2Za(pkX, pkY, "1234567812345678".getBytes());        sm3.update(z, 0, z.length);        byte[] p = md;        sm3.update(p, 0, p.length);        byte[] hashData = new byte[32];        sm3.doFinal(hashData, 0);        // e        BigInteger e = new BigInteger(1, hashData);        // k        BigInteger k = null;        BigInteger r = null;        BigInteger s = null;        BigInteger userD = null;        BigInteger x = new BigInteger(1, pkX);        BigInteger pr = new BigInteger(1, prk);        do {            do {                // ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters)                // keypair                // .getPrivate();                k = pr;                // ecpriv.getD().toString(16);//私钥                // kp = ecpub.getQ();//pk                userD = pr;                // r                r = e.add(x);                r = r.mod(ecc_n);            } while (r.equals(BigInteger.ZERO) || r.add(k).equals(ecc_n));            // (1 + dA)~-1            BigInteger da_1 = userD.add(BigInteger.ONE);            da_1 = da_1.modInverse(ecc_n);            // s            s = r.multiply(userD);            s = k.subtract(s).mod(ecc_n);            s = da_1.multiply(s).mod(ecc_n);        } while (s.equals(BigInteger.ZERO));        byte[] btRS = new byte[64];        byte[] btR = r.toByteArray();        byte[] btS = s.toByteArray();        System.arraycopy(btR, btR.length - 32, btRS, 0, 32);        System.arraycopy(btS, btS.length - 32, btRS, 32, 32);        r.toByteArray();        s.toByteArray();        byte[] encode = Base64.encode(btRS);        System.out.println("sssssss-------r" + r.toString(16));        System.out.println("sssssss-------s" + s.toString(16));        return new String(encode);    }    public boolean Verify(byte[] msg, byte[] signData) {        byte[] certPK = publicKey.getEncoded();        byte[] pkX = SubByte(certPK, 0, 32);        byte[] pkY = SubByte(certPK, 32, 32);//        System.out.println("\n");//        BigInteger biX = new BigInteger(1, pkX);//        BigInteger biY = new BigInteger(1, pkY);//        ECFieldElement x = new Fp(ecc_p, biX);//        ECFieldElement y = new Fp(ecc_p, biY);        ECPoint userKey = publicKey;        //        SM3Digest sm3 = new SM3Digest();        byte[] sm2Za = sm3.getSM2Za(pkX, pkY, "1234567812345678".getBytes());        System.out.println("\n");        // printHexString(sm2Za);        sm3.update(sm2Za, 0, sm2Za.length);        System.out.println("\n");        // printHexString(sm2Za);        System.out.println("\n");        byte[] p = msg;        sm3.update(p, 0, p.length);        System.out.println("\n");        byte[] md = new byte[32];        sm3.doFinal(md, 0);        byte[] btRS = signData;        byte[] btR = SubByte(btRS, 0, btRS.length / 2);        byte[] btS = SubByte(btRS, btR.length, btRS.length - btR.length);        BigInteger r = new BigInteger(1, btR);        BigInteger s = new BigInteger(1, btS);        // e_        BigInteger e = new BigInteger(1, md);        // t        BigInteger t = r.add(s).mod(ecc_n);        if (t.equals(BigInteger.ZERO))            return false;        // x1y1        ECPoint x1y1 = ecc_point_g.multiply(s);        x1y1 = x1y1.add(userKey.multiply(t));        // R        BigInteger R = e.add(x1y1.getX().toBigInteger()).mod(ecc_n);        return r.equals(R);    }}

原创粉丝点击