| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289 |
- package com.security.cipher.sm;
- import org.bouncycastle.asn1.ASN1EncodableVector;
- import org.bouncycastle.asn1.ASN1InputStream;
- import org.bouncycastle.asn1.ASN1Sequence;
- import org.bouncycastle.asn1.DERInteger;
- import org.bouncycastle.asn1.DERObject;
- import org.bouncycastle.asn1.DERSequence;
- import org.bouncycastle.math.ec.ECPoint;
- import java.io.ByteArrayInputStream;
- import java.io.IOException;
- import java.math.BigInteger;
- import java.util.Enumeration;
- public class SM2Utils
- {
- public static byte[] encrypt(byte[] publicKey, byte[] data) throws IOException
- {
- if (publicKey == null || publicKey.length == 0)
- {
- return null;
- }
-
- if (data == null || data.length == 0)
- {
- return null;
- }
-
- byte[] source = new byte[data.length];
- System.arraycopy(data, 0, source, 0, data.length);
-
- Cipher cipher = new Cipher();
- SM2 sm2 = SM2.Instance();
- ECPoint userKey = sm2.ecc_curve.decodePoint(publicKey);
-
- ECPoint c1 = cipher.Init_enc(sm2, userKey);
- cipher.Encrypt(source);
- byte[] c3 = new byte[32];
- cipher.Dofinal(c3);
- // System.out.println("C1 " + Util.byteToHex(c1.getEncoded()));
- // System.out.println("C2 " + Util.byteToHex(source));
- // System.out.println("C3 " + Util.byteToHex(c3));
- //C1 C2 C3拼装成加密字串
- String encryptdata = Util.encodeHexString(c1.getEncoded())+Util.encodeHexString(source)+Util.encodeHexString(c3);
- return Util.hexStringToBytes(encryptdata);
- /*
- DERInteger x = new DERInteger(c1.getX().toBigInteger());
- DERInteger y = new DERInteger(c1.getY().toBigInteger());
- DEROctetString derDig = new DEROctetString(c3);
- DEROctetString derEnc = new DEROctetString(source);
- ASN1EncodableVector v = new ASN1EncodableVector();
- v.add(x);
- v.add(y);
- v.add(derDig);
- v.add(derEnc);
- DERSequence seq = new DERSequence(v);
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- DEROutputStream dos = new DEROutputStream(bos);
- dos.writeObject(seq);
- return bos.toByteArray();
- */
- }
-
- public static byte[] decrypt(byte[] privateKey, byte[] encryptedData) throws IOException
- {
- if (privateKey == null || privateKey.length == 0)
- {
- return null;
- }
-
- if (encryptedData == null || encryptedData.length == 0)
- {
- return null;
- }
-
- //byte[] enc = new byte[encryptedData.length];
- //System.arraycopy(encryptedData, 0, enc, 0, encryptedData.length);
- //加密字节数组转换为十六进制的字符串 长度变为encryptedData.length * 2
- String data = Util.byteToHex(encryptedData);
- /***分解加密字串
- * (C1 = C1标志位2位 + C1实体部分128位 = 130)
- * (C3 = C3实体部分64位 = 64)
- * (C2 = encryptedData.length * 2 - C1长度 - C2长度)
- */
- 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 = SM2.Instance();
- BigInteger userD = new BigInteger(1, privateKey);
- /*
- ByteArrayInputStream bis = new ByteArrayInputStream(enc);
- ASN1InputStream dis = new ASN1InputStream(bis);
- DERObject derObj = dis.readObject();
- ASN1Sequence asn1 = (ASN1Sequence) derObj;
- DERInteger x = (DERInteger) asn1.getObjectAt(0);
- DERInteger y = (DERInteger) asn1.getObjectAt(1);
- ECPoint c1 = sm2.ecc_curve.createPoint(x.getValue(), y.getValue(), true);
-
- Cipher cipher = new Cipher();
- cipher.Init_dec(userD, c1);
- DEROctetString data = (DEROctetString) asn1.getObjectAt(3);
- enc = data.getOctets();
- cipher.Decrypt(enc);
- byte[] c3 = new byte[32];
- cipher.Dofinal(c3);
- return enc;
- */
- //通过C1实体字节来生成ECPoint
- ECPoint c1 = sm2.ecc_curve.decodePoint(c1Bytes);
- Cipher cipher = new Cipher();
- cipher.Init_dec(userD, c1);
- cipher.Decrypt(c2);
- cipher.Dofinal(c3);
- //返回解密结果
- return c2;
- }
-
- public static byte[] sign(byte[] userId, byte[] privateKey, byte[] sourceData) throws IOException
- {
- if (privateKey == null || privateKey.length == 0)
- {
- return null;
- }
-
- if (sourceData == null || sourceData.length == 0)
- {
- return null;
- }
-
- SM2 sm2 = SM2.Instance();
- BigInteger userD = new BigInteger(privateKey);
- System.out.println("userD: " + userD.toString(16));
- System.out.println("");
-
- ECPoint userKey = sm2.ecc_point_g.multiply(userD);
- System.out.println("椭圆曲线点X: " + userKey.getX().toBigInteger().toString(16));
- System.out.println("椭圆曲线点Y: " + userKey.getY().toBigInteger().toString(16));
- System.out.println("");
-
- SM3Digest sm3 = new SM3Digest();
- byte[] z = sm2.sm2GetZ(userId, userKey);
- System.out.println("SM3摘要Z: " + Util.getHexString(z));
- System.out.println("");
-
- System.out.println("M: " + Util.getHexString(sourceData));
- System.out.println("");
-
- sm3.update(z, 0, z.length);
- sm3.update(sourceData, 0, sourceData.length);
- byte[] md = new byte[32];
- sm3.doFinal(md, 0);
-
- System.out.println("SM3摘要值: " + Util.getHexString(md));
- System.out.println("");
-
- SM2Result sm2Result = new SM2Result();
- sm2.sm2Sign(md, userD, userKey, sm2Result);
- System.out.println("r: " + sm2Result.r.toString(16));
- System.out.println("s: " + sm2Result.s.toString(16));
- System.out.println("");
-
- DERInteger d_r = new DERInteger(sm2Result.r);
- DERInteger d_s = new DERInteger(sm2Result.s);
- ASN1EncodableVector v2 = new ASN1EncodableVector();
- v2.add(d_r);
- v2.add(d_s);
- DERObject sign = new DERSequence(v2);
- byte[] signdata = sign.getDEREncoded();
- return signdata;
- }
-
- @SuppressWarnings("unchecked")
- public static boolean verifySign(byte[] userId, byte[] publicKey, byte[] sourceData, byte[] signData) throws IOException
- {
- if (publicKey == null || publicKey.length == 0)
- {
- return false;
- }
-
- if (sourceData == null || sourceData.length == 0)
- {
- return false;
- }
-
- SM2 sm2 = SM2.Instance();
- ECPoint userKey = sm2.ecc_curve.decodePoint(publicKey);
-
- SM3Digest sm3 = new SM3Digest();
- byte[] z = sm2.sm2GetZ(userId, userKey);
- sm3.update(z, 0, z.length);
- sm3.update(sourceData, 0, sourceData.length);
- byte[] md = new byte[32];
- sm3.doFinal(md, 0);
- System.out.println("SM3摘要值: " + Util.getHexString(md));
- System.out.println("");
-
- ByteArrayInputStream bis = new ByteArrayInputStream(signData);
- ASN1InputStream dis = new ASN1InputStream(bis);
- DERObject derObj = dis.readObject();
- Enumeration<DERInteger> e = ((ASN1Sequence) derObj).getObjects();
- BigInteger r = ((DERInteger)e.nextElement()).getValue();
- BigInteger s = ((DERInteger)e.nextElement()).getValue();
- SM2Result sm2Result = new SM2Result();
- sm2Result.r = r;
- sm2Result.s = s;
- System.out.println("r: " + sm2Result.r.toString(16));
- System.out.println("s: " + sm2Result.s.toString(16));
- System.out.println("");
-
-
- sm2.sm2Verify(md, userKey, sm2Result.r, sm2Result.s, sm2Result);
- return sm2Result.r.equals(sm2Result.R);
- }
- /*
- public static void main(String[] args) throws Exception
- {
- String plainText = "message digest";
- byte[] sourceData = plainText.getBytes();
-
- // 国密规范测试私钥
- String prik = "128B2FA8BD433C6C068C8D803DFF79792A519A55171B1B650C23661D15897263";
- String prikS = new String(Base64.encode(Util.hexToByte(prik)));
- System.out.println("prikS: " + prikS);
- System.out.println("");
-
- // 国密规范测试用户ID
- String userId = "[email protected]";
-
- System.out.println("ID: " + Util.getHexString(userId.getBytes()));
- System.out.println("");
-
- System.out.println("签名: ");
- byte[] c = SM2Utils.sign(userId.getBytes(), Base64.decode(prikS.getBytes()), sourceData);
- System.out.println("sign: " + Util.getHexString(c));
- System.out.println("");
-
- // 国密规范测试公钥
- String pubk = "040AE4C7798AA0F119471BEE11825BE46202BB79E2A5844495E97C04FF4DF2548A7C0240F88F1CD4E16352A73C17B7F16F07353E53A176D684A9FE0C6BB798E857";
- String pubkS = new String(Base64.encode(Util.hexToByte(pubk)));
- System.out.println("pubkS: " + pubkS);
- System.out.println("");
- System.out.println("验签: ");
- boolean vs = SM2Utils.verifySign(userId.getBytes(), Base64.decode(pubkS.getBytes()), sourceData, c);
- System.out.println("验签结果: " + vs);
- System.out.println("");
-
- System.out.println("加密: ");
- byte[] cipherText = SM2Utils.encrypt(Base64.decode(pubkS.getBytes()), sourceData);
- System.out.println(new String(Base64.encode(cipherText)));
- System.out.println("");
-
- System.out.println("解密: ");
- plainText = new String(SM2Utils.decrypt(Base64.decode(prikS.getBytes()), cipherText));
- System.out.println(plainText);
-
- }
- */
- public static void SM2_TEST() throws Exception
- {
- String plainText = "1122334455667788";
- byte[] sourceData = Util.hexStringToBytes(plainText);
- // 国密规范测试私钥
- String prik = "969FC0F73FA117A040B37D5B5018382A74D40590EAA02809B87FA09196F8276D";
- // 国密规范测试公钥
- String pubk = "04ABC2230A05A72CEB667B20019C4F2A580E4D0A3BE9D20BF914565AB3B82631E1C0E15803FA3ADE3E6D9EEF293CBD8BAECC51D82B61404A39584198B6985686FB";
- System.out.println("加密: ");
- byte[] cipherText = SM2Utils.encrypt(Util.hexStringToBytes(pubk), sourceData);
- System.out.println(Util.encodeHexString(cipherText));
- System.out.println("");
- System.out.println("解密: ");
- String data = "04ADE0AFDD137B5E9B2CF3F4D71D329E06F3E8006598A12BB8B6A4B31F8E1D2266EFB1015812E10DC058940A3C8AB8BA29FFE788F85A5D236C3526BBA8D0E0A10D5806DAE0C2DEFADC1A49CE657D4311CDF65D9F38F1CF5004F2E4BA922EA538C9E75007CA0C7AADD8";
- plainText = Util.encodeHexString(SM2Utils.decrypt(Util.hexStringToBytes(prik), Util.hexStringToBytes(data)));
- System.out.println(plainText);
- }
- }
|