代码

package com.example.demo.MIMAXUE.SM;import java.io.*;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.Arrays;import org.apache.commons.io.FileUtils;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECPoint;/*** SM2公钥加密算法实现 包括 -签名,验签 -密钥交换 -公钥加密,私钥解密** @author Potato**/
public class SM2 {private static BigInteger n = new BigInteger("FFFFFFFE" + "FFFFFFFF" + "FFFFFFFF" + "FFFFFFFF" + "7203DF6B" + "21C6052B" + "53BBF409" + "39D54123", 16);private static BigInteger p = new BigInteger("FFFFFFFE" + "FFFFFFFF" + "FFFFFFFF" + "FFFFFFFF" + "FFFFFFFF" + "00000000" + "FFFFFFFF" + "FFFFFFFF", 16);private static BigInteger a = new BigInteger("FFFFFFFE" + "FFFFFFFF" + "FFFFFFFF" + "FFFFFFFF" + "FFFFFFFF" + "00000000" + "FFFFFFFF" + "FFFFFFFC", 16);private static BigInteger b = new BigInteger("28E9FA9E" + "9D9F5E34" + "4D5A9E4B" + "CF6509A7" + "F39789F5" + "15AB8F92" + "DDBCBD41" + "4D940E93", 16);private static BigInteger gx = new BigInteger("32C4AE2C" + "1F198119" + "5F990446" + "6A39C994" + "8FE30BBF" + "F2660BE1" + "715A4589" + "334C74C7", 16);private static BigInteger gy = new BigInteger("BC3736A2" + "F4F6779C" + "59BDCEE3" + "6B692153" + "D0A9877C" + "C62A4740" + "02DF32E5" + "2139F0A0", 16);private static ECDomainParameters ecc_bc_spec;private static int w = (int) Math.ceil(n.bitLength() * 1.0 / 2) - 1;private static BigInteger _2w = new BigInteger("2").pow(w);private static final int DIGEST_LENGTH = 32;private static SecureRandom random = new SecureRandom();private static ECCurve.Fp curve;private static ECPoint G;private boolean debug = false;public boolean isDebug() {return debug;}public void setDebug(boolean debug) {this.debug = debug;}/*** 以16进制打印字节数组** @param b*/public static void printHexString(byte[] b) {for (int i = 0; i < b.length; i++) {String hex = Integer.toHexString(b[i] & 0xFF);if (hex.length() == 1) {hex = '0' + hex;}System.out.print(hex.toUpperCase());}System.out.println();}/*** 随机数生成器** @param max* @return*/private static BigInteger random(BigInteger max) {BigInteger r = new BigInteger(256, random);// int count = 1;while (r.compareTo(max) >= 0) {r = new BigInteger(128, random);// count++;}// System.out.println("count: " + count);return r;}/*** 判断字节数组是否全0** @param buffer* @return*/private boolean allZero(byte[] buffer) {for (int i = 0; i < buffer.length; i++) {if (buffer[i] != 0)return false;}return true;}public byte[] encryptFile(ECPoint publicKey) throws IOException {StringBuffer fileData = new StringBuffer();//"G:\\jjDown\\shengyue.mp4"BufferedReader reader = new BufferedReader(new FileReader("G:\\jjDown\\350.mp4"));char[] buf = new char[1024];int numRead=0;while((numRead=reader.read(buf)) != -1){String readData = String.valueOf(buf, 0, numRead);fileData.append(readData);}//缓冲区使用完必须关掉reader.close();//return fileData.toString();// File file = new File("C:\\Users\\12236\\Desktop\\tangtang.txt");
//        try {//            String content = FileUtils.readFileToString(file);
//            System.out.println("Contents of file: " + content);
//        } catch (IOException e) {//            e.printStackTrace();
//        }byte[] result = encrypt(fileData.toString(), publicKey);return result;}public byte[] encryptFile2(ECPoint publicKey) throws IOException {StringBuffer fileData = new StringBuffer();//"G:\\jjDown\\shengyue.mp4"BufferedReader reader = new BufferedReader(new FileReader("G:\\jjDown\\0989.mp4"));char[] buf = new char[1024];int numRead=0;while((numRead=reader.read(buf)) != -1){String readData = String.valueOf(buf, 0, numRead);fileData.append(readData);}//缓冲区使用完必须关掉reader.close();//return fileData.toString();// File file = new File("C:\\Users\\12236\\Desktop\\tangtang.txt");
//        try {//            String content = FileUtils.readFileToString(file);
//            System.out.println("Contents of file: " + content);
//        } catch (IOException e) {//            e.printStackTrace();
//        }byte[] result = encrypt(fileData.toString(), publicKey);return result;}/*** 公钥加密** @param input*            加密原文* @param publicKey*            公钥* @return*/public byte[] encrypt(String input, ECPoint publicKey) {byte[] inputBuffer = input.getBytes();if (debug)printHexString(inputBuffer);byte[] C1Buffer;ECPoint kpb;byte[] t;do {/* 1 产生随机数k,k属于[1, n-1] */BigInteger k = random(n);if (debug) {System.out.print("k: ");printHexString(k.toByteArray());}/* 2 计算椭圆曲线点C1 = [k]G = (x1, y1) */ECPoint C1 = G.multiply(k);C1Buffer = C1.getEncoded(false);if (debug) {System.out.print("C1: ");printHexString(C1Buffer);}/** 3 计算椭圆曲线点 S = [h]Pb*/BigInteger h = ecc_bc_spec.getH();if (h != null) {ECPoint S = publicKey.multiply(h);if (S.isInfinity())throw new IllegalStateException();}/* 4 计算 [k]PB = (x2, y2) */kpb = publicKey.multiply(k).normalize();/* 5 计算 t = KDF(x2||y2, klen) */byte[] kpbBytes = kpb.getEncoded(false);t = KDF(kpbBytes, inputBuffer.length);// DerivationFunction kdf = new KDF1BytesGenerator(new// ShortenedDigest(new SHA256Digest(), DIGEST_LENGTH));//// t = new byte[inputBuffer.length];// kdf.init(new ISO18033KDFParameters(kpbBytes));// kdf.generateBytes(t, 0, t.length);} while (allZero(t));/* 6 计算C2=M^t */byte[] C2 = new byte[inputBuffer.length];for (int i = 0; i < inputBuffer.length; i++) {C2[i] = (byte) (inputBuffer[i] ^ t[i]);}/* 7 计算C3 = Hash(x2 || M || y2) */byte[] C3 = sm3hash(kpb.getXCoord().toBigInteger().toByteArray(), inputBuffer,kpb.getYCoord().toBigInteger().toByteArray());/* 8 输出密文 C=C1 || C2 || C3 */byte[] encryptResult = new byte[C1Buffer.length + C2.length + C3.length];System.arraycopy(C1Buffer, 0, encryptResult, 0, C1Buffer.length);System.arraycopy(C2, 0, encryptResult, C1Buffer.length, C2.length);System.arraycopy(C3, 0, encryptResult, C1Buffer.length + C2.length, C3.length);if (debug) {System.out.print("密文: ");printHexString(encryptResult);}return encryptResult;}/*** 私钥解密** @param encryptData*            密文数据字节数组* @param privateKey*            解密私钥* @return*/public String decrypt(byte[] encryptData, BigInteger privateKey) {if (debug)System.out.println("encryptData length: " + encryptData.length);byte[] C1Byte = new byte[65];System.arraycopy(encryptData, 0, C1Byte, 0, C1Byte.length);ECPoint C1 = curve.decodePoint(C1Byte).normalize();/** 计算椭圆曲线点 S = [h]C1 是否为无穷点*/BigInteger h = ecc_bc_spec.getH();if (h != null) {ECPoint S = C1.multiply(h);if (S.isInfinity())throw new IllegalStateException();}/* 计算[dB]C1 = (x2, y2) */ECPoint dBC1 = C1.multiply(privateKey).normalize();/* 计算t = KDF(x2 || y2, klen) */byte[] dBC1Bytes = dBC1.getEncoded(false);int klen = encryptData.length - 65 - DIGEST_LENGTH;byte[] t = KDF(dBC1Bytes, klen);// DerivationFunction kdf = new KDF1BytesGenerator(new// ShortenedDigest(new SHA256Digest(), DIGEST_LENGTH));// if (debug)// System.out.println("klen = " + klen);// kdf.init(new ISO18033KDFParameters(dBC1Bytes));// kdf.generateBytes(t, 0, t.length);if (allZero(t)) {System.err.println("all zero");throw new IllegalStateException();}/* 5 计算M'=C2^t */byte[] M = new byte[klen];for (int i = 0; i < M.length; i++) {M[i] = (byte) (encryptData[C1Byte.length + i] ^ t[i]);}if (debug)printHexString(M);/* 6 计算 u = Hash(x2 || M' || y2) 判断 u == C3是否成立 */byte[] C3 = new byte[DIGEST_LENGTH];if (debug)try {System.out.println("M = " + new String(M, "UTF8"));} catch (UnsupportedEncodingException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}System.arraycopy(encryptData, encryptData.length - DIGEST_LENGTH, C3, 0, DIGEST_LENGTH);byte[] u = sm3hash(dBC1.getXCoord().toBigInteger().toByteArray(), M,dBC1.getYCoord().toBigInteger().toByteArray());if (Arrays.equals(u, C3)) {if (debug)System.out.println("解密成功");try {return new String(M, "UTF8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}return null;} else {if (debug) {System.out.print("u = ");printHexString(u);System.out.print("C3 = ");printHexString(C3);System.err.println("解密验证失败");}return null;}}// /**// * SHA摘要// * @param x2// * @param M// * @param y2// * @return// */// private byte[] calculateHash(BigInteger x2, byte[] M, BigInteger y2) {// ShortenedDigest digest = new ShortenedDigest(new SHA256Digest(),// DIGEST_LENGTH);// byte[] buf = x2.toByteArray();// digest.update(buf, 0, buf.length);// digest.update(M, 0, M.length);// buf = y2.toByteArray();// digest.update(buf, 0, buf.length);//// buf = new byte[DIGEST_LENGTH];// digest.doFinal(buf, 0);//// return buf;// }/*** 判断是否在范围内** @param param* @param min* @param max* @return*/private boolean between(BigInteger param, BigInteger min, BigInteger max) {if (param.compareTo(min) >= 0 && param.compareTo(max) < 0) {return true;} else {return false;}}/*** 判断生成的公钥是否合法** @param publicKey* @return*/private boolean checkPublicKey(ECPoint publicKey) {if (!publicKey.isInfinity()) {BigInteger x = publicKey.getXCoord().toBigInteger();BigInteger y = publicKey.getYCoord().toBigInteger();if (between(x, new BigInteger("0"), p) && between(y, new BigInteger("0"), p)) {BigInteger xResult = x.pow(3).add(a.multiply(x)).add(b).mod(p);if (debug)System.out.println("xResult: " + xResult.toString());BigInteger yResult = y.pow(2).mod(p);if (debug)System.out.println("yResult: " + yResult.toString());if (yResult.equals(xResult) && publicKey.multiply(n).isInfinity()) {return true;}}}return false;}/*** 生成密钥对** @return*/public SM2KeyPair generateKeyPair() {BigInteger d = random(n.subtract(new BigInteger("1")));SM2KeyPair keyPair = new SM2KeyPair(G.multiply(d).normalize(), d);if (checkPublicKey(keyPair.getPublicKey())) {if (debug)System.out.println("generate key successfully");return keyPair;} else {if (debug)System.err.println("generate key failed");return null;}}public SM2() {curve = new ECCurve.Fp(p, // qa, // ab); // bG = curve.createPoint(gx, gy);ecc_bc_spec = new ECDomainParameters(curve, G, n);}public SM2(boolean debug) {this();this.debug = debug;}/*** 导出公钥到本地** @param publicKey* @param path*/public void exportPublicKey(ECPoint publicKey, String path) {File file = new File(path);try {if (!file.exists())file.createNewFile();byte buffer[] = publicKey.getEncoded(false);FileOutputStream fos = new FileOutputStream(file);fos.write(buffer);fos.close();} catch (IOException e) {e.printStackTrace();}}/*** 从本地导入公钥** @param path* @return*/public ECPoint importPublicKey(String path) {File file = new File(path);try {if (!file.exists())return null;FileInputStream fis = new FileInputStream(file);ByteArrayOutputStream baos = new ByteArrayOutputStream();byte buffer[] = new byte[16];int size;while ((size = fis.read(buffer)) != -1) {baos.write(buffer, 0, size);}fis.close();return curve.decodePoint(baos.toByteArray());} catch (IOException e) {e.printStackTrace();}return null;}/*** 导出私钥到本地** @param privateKey* @param path*/public void exportPrivateKey(BigInteger privateKey, String path) {File file = new File(path);try {if (!file.exists())file.createNewFile();ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));oos.writeObject(privateKey);oos.close();} catch (IOException e) {e.printStackTrace();}}/*** 从本地导入私钥** @param path* @return*/public BigInteger importPrivateKey(String path) {File file = new File(path);try {if (!file.exists())return null;FileInputStream fis = new FileInputStream(file);ObjectInputStream ois = new ObjectInputStream(fis);BigInteger res = (BigInteger) (ois.readObject());ois.close();fis.close();return res;} catch (Exception e) {e.printStackTrace();}return null;}/*** 字节数组拼接** @param params* @return*/private static byte[] join(byte[]... params) {ByteArrayOutputStream baos = new ByteArrayOutputStream();byte[] res = null;try {for (int i = 0; i < params.length; i++) {baos.write(params[i]);}res = baos.toByteArray();} catch (IOException e) {e.printStackTrace();}return res;}/*** sm3摘要** @param params* @return*/private static byte[] sm3hash(byte[]... params) {byte[] res = null;try {res = SM3.hash(join(params));} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return res;}/*** 取得用户标识字节数组** @param IDA* @param aPublicKey* @return*/private static byte[] ZA(String IDA, ECPoint aPublicKey) {byte[] idaBytes = IDA.getBytes();int entlenA = idaBytes.length * 8;byte[] ENTLA = new byte[] { (byte) (entlenA & 0xFF00), (byte) (entlenA & 0x00FF) };byte[] ZA = sm3hash(ENTLA, idaBytes, a.toByteArray(), b.toByteArray(), gx.toByteArray(), gy.toByteArray(),aPublicKey.getXCoord().toBigInteger().toByteArray(),aPublicKey.getYCoord().toBigInteger().toByteArray());return ZA;}/*** 签名** @param M*            签名信息* @param IDA*            签名方唯一标识* @param keyPair*            签名方密钥对* @return 签名*/public Signature sign(String M, String IDA, SM2KeyPair keyPair) {byte[] ZA = ZA(IDA, keyPair.getPublicKey());byte[] M_ = join(ZA, M.getBytes());BigInteger e = new BigInteger(1, sm3hash(M_));// BigInteger k = new BigInteger(// "6CB28D99 385C175C 94F94E93 4817663F C176D925 DD72B727 260DBAAE// 1FB2F96F".replace(" ", ""), 16);BigInteger k;BigInteger r;do {k = random(n);ECPoint p1 = G.multiply(k).normalize();BigInteger x1 = p1.getXCoord().toBigInteger();r = e.add(x1);r = r.mod(n);} while (r.equals(BigInteger.ZERO) || r.add(k).equals(n));BigInteger s = ((keyPair.getPrivateKey().add(BigInteger.ONE).modInverse(n)).multiply((k.subtract(r.multiply(keyPair.getPrivateKey()))).mod(n))).mod(n);return new Signature(r, s);}/*** 验签** @param M*            签名信息* @param signature*            签名* @param IDA*            签名方唯一标识* @param aPublicKey*            签名方公钥* @return true or false*/public boolean verify(String M, Signature signature, String IDA, ECPoint aPublicKey) {if (!between(signature.r, BigInteger.ONE, n))return false;if (!between(signature.s, BigInteger.ONE, n))return false;byte[] M_ = join(ZA(IDA, aPublicKey), M.getBytes());BigInteger e = new BigInteger(1, sm3hash(M_));BigInteger t = signature.r.add(signature.s).mod(n);if (t.equals(BigInteger.ZERO))return false;ECPoint p1 = G.multiply(signature.s).normalize();ECPoint p2 = aPublicKey.multiply(t).normalize();BigInteger x1 = p1.add(p2).normalize().getXCoord().toBigInteger();BigInteger R = e.add(x1).mod(n);if (R.equals(signature.r))return true;return false;}/*** 密钥派生函数** @param Z* @param klen*            生成klen字节数长度的密钥* @return*/private static byte[] KDF(byte[] Z, int klen) {int ct = 1;int end = (int) Math.ceil(klen * 1.0 / 32);ByteArrayOutputStream baos = new ByteArrayOutputStream();try {for (int i = 1; i < end; i++) {baos.write(sm3hash(Z, SM3.toByteArray(ct)));ct++;}byte[] last = sm3hash(Z, SM3.toByteArray(ct));if (klen % 32 == 0) {baos.write(last);} elsebaos.write(last, 0, klen % 32);return baos.toByteArray();} catch (Exception e) {e.printStackTrace();}return null;}/*** 传输实体类** @author Potato**/private static class TransportEntity implements Serializable {final byte[] R; //R点final byte[] S; //验证Sfinal byte[] Z; //用户标识final byte[] K; //公钥public TransportEntity(byte[] r, byte[] s,byte[] z,ECPoint pKey) {R = r;S = s;Z=z;K=pKey.getEncoded(false);}}/*** 密钥协商辅助类** @author Potato**/public static class KeyExchange {BigInteger rA;ECPoint RA;ECPoint V;byte[] Z;byte[] key;String ID;SM2KeyPair keyPair;public KeyExchange(String ID,SM2KeyPair keyPair) {this.ID=ID;this.keyPair = keyPair;this.Z=ZA(ID, keyPair.getPublicKey());}/*** 密钥协商发起第一步** @return*/public TransportEntity keyExchange_1() {rA = random(n);// rA=new BigInteger("83A2C9C8 B96E5AF7 0BD480B4 72409A9A 327257F1// EBB73F5B 073354B2 48668563".replace(" ", ""),16);RA = G.multiply(rA).normalize();return new TransportEntity(RA.getEncoded(false), null,Z,keyPair.getPublicKey());}/*** 密钥协商响应方** @param entity 传输实体* @return*/public TransportEntity keyExchange_2(TransportEntity entity) {BigInteger rB = random(n);// BigInteger rB=new BigInteger("33FE2194 0342161C 55619C4A 0C060293// D543C80A F19748CE 176D8347 7DE71C80".replace(" ", ""),16);ECPoint RB = G.multiply(rB).normalize();this.rA=rB;this.RA=RB;BigInteger x2 = RB.getXCoord().toBigInteger();x2 = _2w.add(x2.and(_2w.subtract(BigInteger.ONE)));BigInteger tB = keyPair.getPrivateKey().add(x2.multiply(rB)).mod(n);ECPoint RA = curve.decodePoint(entity.R).normalize();BigInteger x1 = RA.getXCoord().toBigInteger();x1 = _2w.add(x1.and(_2w.subtract(BigInteger.ONE)));ECPoint aPublicKey=curve.decodePoint(entity.K).normalize();ECPoint temp = aPublicKey.add(RA.multiply(x1).normalize()).normalize();ECPoint V = temp.multiply(ecc_bc_spec.getH().multiply(tB)).normalize();if (V.isInfinity())throw new IllegalStateException();this.V=V;byte[] xV = V.getXCoord().toBigInteger().toByteArray();byte[] yV = V.getYCoord().toBigInteger().toByteArray();byte[] KB = KDF(join(xV, yV, entity.Z, this.Z), 16);key = KB;System.out.print("协商得B密钥:");printHexString(KB);byte[] sB = sm3hash(new byte[] { 0x02 }, yV,sm3hash(xV, entity.Z, this.Z, RA.getXCoord().toBigInteger().toByteArray(),RA.getYCoord().toBigInteger().toByteArray(), RB.getXCoord().toBigInteger().toByteArray(),RB.getYCoord().toBigInteger().toByteArray()));return new TransportEntity(RB.getEncoded(false), sB,this.Z,keyPair.getPublicKey());}/*** 密钥协商发起方第二步** @param entity 传输实体*/public TransportEntity keyExchange_3(TransportEntity entity) {BigInteger x1 = RA.getXCoord().toBigInteger();x1 = _2w.add(x1.and(_2w.subtract(BigInteger.ONE)));BigInteger tA = keyPair.getPrivateKey().add(x1.multiply(rA)).mod(n);ECPoint RB = curve.decodePoint(entity.R).normalize();BigInteger x2 = RB.getXCoord().toBigInteger();x2 = _2w.add(x2.and(_2w.subtract(BigInteger.ONE)));ECPoint bPublicKey=curve.decodePoint(entity.K).normalize();ECPoint temp = bPublicKey.add(RB.multiply(x2).normalize()).normalize();ECPoint U = temp.multiply(ecc_bc_spec.getH().multiply(tA)).normalize();if (U.isInfinity())throw new IllegalStateException();this.V=U;byte[] xU = U.getXCoord().toBigInteger().toByteArray();byte[] yU = U.getYCoord().toBigInteger().toByteArray();byte[] KA = KDF(join(xU, yU,this.Z, entity.Z), 16);key = KA;System.out.print("协商得A密钥:");printHexString(KA);byte[] s1= sm3hash(new byte[] { 0x02 }, yU,sm3hash(xU, this.Z, entity.Z, RA.getXCoord().toBigInteger().toByteArray(),RA.getYCoord().toBigInteger().toByteArray(), RB.getXCoord().toBigInteger().toByteArray(),RB.getYCoord().toBigInteger().toByteArray()));if(Arrays.equals(entity.S, s1))System.out.println("B->A 密钥确认成功");elseSystem.out.println("B->A 密钥确认失败");byte[] sA= sm3hash(new byte[] { 0x03 }, yU,sm3hash(xU, this.Z, entity.Z, RA.getXCoord().toBigInteger().toByteArray(),RA.getYCoord().toBigInteger().toByteArray(), RB.getXCoord().toBigInteger().toByteArray(),RB.getYCoord().toBigInteger().toByteArray()));return new TransportEntity(RA.getEncoded(false), sA,this.Z,keyPair.getPublicKey());}/*** 密钥确认最后一步** @param entity 传输实体*/public void keyExchange_4(TransportEntity entity) {byte[] xV = V.getXCoord().toBigInteger().toByteArray();byte[] yV = V.getYCoord().toBigInteger().toByteArray();ECPoint RA = curve.decodePoint(entity.R).normalize();byte[] s2= sm3hash(new byte[] { 0x03 }, yV,sm3hash(xV, entity.Z, this.Z, RA.getXCoord().toBigInteger().toByteArray(),RA.getYCoord().toBigInteger().toByteArray(), this.RA.getXCoord().toBigInteger().toByteArray(),this.RA.getYCoord().toBigInteger().toByteArray()));if(Arrays.equals(entity.S, s2))System.out.println("A->B 密钥确认成功");elseSystem.out.println("A->B 密钥确认失败");}}public static void main(String[] args) throws UnsupportedEncodingException {SM2 sm02 = new SM2();// BigInteger px = new BigInteger(// "0AE4C779 8AA0F119 471BEE11 825BE462 02BB79E2 A5844495 E97C04FF// 4DF2548A".replace(" ", ""), 16);// BigInteger py = new BigInteger(// "7C0240F8 8F1CD4E1 6352A73C 17B7F16F 07353E53 A176D684 A9FE0C6B// B798E857".replace(" ", ""), 16);// ECPoint publicKey = sm02.curve.createPoint(px, py);// BigInteger privateKey = new BigInteger(// "128B2FA8 BD433C6C 068C8D80 3DFF7979 2A519A55 171B1B65 0C23661D// 15897263".replace(" ", ""), 16);// SM2KeyPair keyPair = sm02.generateKeyPair();// ECPoint publicKey=keyPair.getPublicKey();// BigInteger privateKey=keyPair.getPrivateKey();// sm02.exportPublicKey(publicKey, "E:/publickey.pem");// sm02.exportPrivateKey(privateKey, "E:/privatekey.pem");System.out.println("-----------------公钥加密与解密-----------------");ECPoint publicKey = sm02.importPublicKey("E:/publickey.pem");BigInteger privateKey = sm02.importPrivateKey("E:/privatekey.pem");byte[] data = sm02.encrypt("测试加密aaaaaaaaaaa123aabb", publicKey);System.out.print("密文:");SM2.printHexString(data);System.out.println("解密后明文:" + sm02.decrypt(data, privateKey));System.out.println("-----------------签名与验签-----------------");String IDA = "Heartbeats";String M = "要签名的信息";Signature signature = sm02.sign(M, IDA, new SM2KeyPair(publicKey, privateKey));System.out.println("用户标识:" + IDA);System.out.println("签名信息:" + M);System.out.println("数字签名:" + signature);System.out.println("验证签名:" + sm02.verify(M, signature, IDA, publicKey));System.out.println("-----------------密钥协商-----------------");String aID = "AAAAAAAAAAAAA";SM2KeyPair aKeyPair = sm02.generateKeyPair();KeyExchange aKeyExchange = new KeyExchange(aID,aKeyPair);String bID = "BBBBBBBBBBBBB";SM2KeyPair bKeyPair = sm02.generateKeyPair();KeyExchange bKeyExchange = new KeyExchange(bID,bKeyPair);TransportEntity entity1 = aKeyExchange.keyExchange_1();TransportEntity entity2 = bKeyExchange.keyExchange_2(entity1);TransportEntity entity3 = aKeyExchange.keyExchange_3(entity2);bKeyExchange.keyExchange_4(entity3);}public static class Signature {BigInteger r;BigInteger s;public Signature(BigInteger r, BigInteger s) {this.r = r;this.s = s;}public String toString() {return r.toString(16) + "," + s.toString(16);}}
}
package com.example.demo.MIMAXUE.SM;import java.math.BigInteger;import org.bouncycastle.math.ec.ECPoint;/*** SM2密钥对Bean* @author Potato**/
public class SM2KeyPair {private final ECPoint publicKey;private final BigInteger privateKey;SM2KeyPair(ECPoint publicKey, BigInteger privateKey) {this.publicKey = publicKey;this.privateKey = privateKey;}public ECPoint getPublicKey() {return publicKey;}public BigInteger getPrivateKey() {return privateKey;}}
package com.example.demo.MIMAXUE.SM;import org.bouncycastle.math.ec.ECPoint;import java.io.IOException;
import java.math.BigInteger;public class SM2Test {public static void main(String[] args) throws IOException {Long avgENCTime = 0L;Long avgDecTime = 0L;for(int i =0;i<10;i++){SM2 sm2 = new SM2();SM2KeyPair keys = sm2.generateKeyPair();BigInteger privateKey = keys.getPrivateKey();ECPoint publicKey = keys.getPublicKey();Long startTime = System.currentTimeMillis();byte[] encryptMessage = sm2.encryptFile(publicKey);//System.out.println("encrypt message\t"+encryptMessage);Long endTime = System.currentTimeMillis();System.out.println("sm2加密花费时间" + (endTime - startTime) + "ms");Long startTime1 = System.currentTimeMillis();String decryptMessage = sm2.decrypt(encryptMessage, privateKey);Long endTime1 = System.currentTimeMillis();System.out.println("sm2解密花费时间" + (endTime1 - startTime1) + "ms");avgENCTime+=(endTime-startTime);avgDecTime+=(endTime1-startTime1);//System.out.println("decrypt message\t"+decryptMessage);}System.out.println("********************************************************************************");System.out.println("aes平均加密花费时间" + avgENCTime/10 + "ms");System.out.println("aes平均加密花费时间" + avgDecTime/10 + "ms");}
}

国密SM2非对称加密算法(对本地文件的加解密)代码展示相关推荐

  1. Spring Security-用户密码自定义国密SM2加密

    为什么80%的码农都做不了架构师?>>>    由于甲方要求需要把密码的加密方式改为国密SM2的方式,网上看了一些写的代码,结合了一下SpringSecurity用户自定义加密,直接 ...

  2. C#国密SM2加密算法实现

    最近在做数据上报,上报数据需要使用国密SM2加密算法加密后上传,以前没接触过过这个东东,所以做个简单记录,平台提供给加密的公钥,让后我们根据公钥将数据加密后,提交给接口,以保证数据安全传输. 实现代码 ...

  3. php gmssl,支持国密SM2/SM3/SM4/SM9/ZUC/SSL的密码工具箱GmSSL

    GmSSL概述 GmSSL是一个开源的密码工具箱,支持SM2/SM3/SM4/SM9/ZUC等国密(国家商用密码)算法.SM2国密数字证书及基于SM2证书的SSL/TLS安全通信协议,支持国密硬件密码 ...

  4. 推荐一款能支持国密SM2的浏览器——密信浏览器

    密信浏览器( MeSince Browser )是基于Chromium开源项目开发的国密安全浏览器,支持国密算法和国密SSL证书,同时也支持国际算法及全球信任SSL证书:密信浏览器使用界面清新,干净. ...

  5. 使用 Python 脚本执行国密 sm2 加解密

    一.场景 工作中的一个场景:Go 需要对信息加解密,但是研究了 GmSSL Go API 文档之后,发现是依赖于 CGO 的,同事配了半天环境没配成功.于是换了一个方法,选择 Go 调 Python ...

  6. 一文告诉你,国密SM2算法有多优秀

    可能很多人都想不到,密码技术是与核技术.航天技术并列的国家三大安全核心技术之一,在保障信息安全,建设行业网络安全环境,增强我国行业信息系统的"安全可控"能力等方面发挥着至为关键的作 ...

  7. 国密SM2算法与RSA算法对比分析

    SM2算法和RSA算法都是公钥密码算法,SM2算法是一种更先进安全的算法,在安全性能.速度性能等方面都优于RSA算法,在我国商用密码体系中被用来替换RSA算法.国家密码管理局于2010年12月17日发 ...

  8. 国密SM2算法(JS加密,C#、Java解密)

    常见的渗透测试会将网站登录时密码使用明文传输视为风险.推荐使用国密算法或者RSA算法对密码进行加密传输. RSA加密(JS加密,C#.Java解密)请参考<RSA对称加密(JS加密,C#.Jav ...

  9. 国密SM2算法的只求理解不求甚解 (4/5)SM2算法加解密协议

    国密SM2算法的只求理解不求甚解 (1/5)前置数学知识:模运算 国密SM2算法的只求理解不求甚解 (2/5)前置数学知识:平面几何 国密SM2算法的只求理解不求甚解 (3/5)SM2算法数学模型 国 ...

  10. 国密SM2前端加密,Java后台解密问题

    背景:要实现请求参数加密的功能,使用的是国密SM2算法,前端向后台发送请求获取公钥,将请求加密发送到后台,后台用对应的私钥进行解密 问题:前端进行加密的请求,后台无法进行解析 解决方案:(此处所用的类 ...

最新文章

  1. php8的jit如何使用,PHP JIT 是什么?PHP8 新特性之 JIT 图文详解
  2. 系统启动过程Linux
  3. 详解-制作根文件系统,并使用yaffs,jffs,nfs挂载系统(2)
  4. 硬件基础 —— 光耦
  5. servlet,session对象的生命周期
  6. 欢迎来到嬴政有条北冥的鱼的博客
  7. Windows下VB6.0开发——关于String类型数据的思考
  8. js排序的时间复杂度_js 排序算法之快速排序
  9. 遗传算法优化的bp神经网络_【首发推荐】农学:基于遗传BP神经网络的采摘机器人手眼标定研究...
  10. 3dsMax7数据导出方法及存在问题
  11. 四种优秀的数据库设计工具
  12. Source must not be null\n\tat org.springframework.util.Assert.notNull(Assert.java:101)
  13. A股明日风口:央行工作会议要求推进法定数字货币研发
  14. 基于Java毕业设计疫情下的居民管理系统源码+系统+mysql+lw文档+部署软件
  15. 39. hive 在使用 count(distinct ) over 时报错,提示 Expression not in GROUP BY key
  16. java游戏2333整合包,[1.12.2][CatServer]基础插件简单MOD冰与火传说整合服务端
  17. pycharm中的py版本与coda3自带版本不统一
  18. iOS全埋点解决方案-采集崩溃
  19. PHPSpreadsheet学习笔记——访问单元格
  20. matlab ext2int函数,Ext2 核心 API 中文详解.pdf

热门文章

  1. 简单工厂模式-工厂模式-抽象工厂模式类图
  2. EJB - 环境设置
  3. 电脑装服务器系统没有网卡驱动,安装win10系统后没有网卡驱动的解决方法
  4. Snagit 截图不清晰问题解决
  5. adodb 连接mysql_PHP程序中使用adodb连接不同数据库的代码实例
  6. 如何对Firefox拓展程序进行修改
  7. 测试方案/测试计划/测试报告
  8. Windows XP3安装internet 信息服务(IIS)时对策
  9. 荣耀路由器w831刷linux,华为荣耀路由器登录入口:荣耀路由器WS831设置指南【图解】...
  10. 用 Python 爬取起点小说网