|
@@ -0,0 +1,561 @@
|
|
|
+package com.usky.system.service.util;
|
|
|
+
|
|
|
+import algo.sm2.util.encoders.Base64;
|
|
|
+import com.ccsp.device.SDFFactory;
|
|
|
+import com.ccsp.device.bean.GlobalData;
|
|
|
+import com.ccsp.device.bean.SM2refPublicKey;
|
|
|
+import com.ccsp.device.bean.SM2refSignature;
|
|
|
+import com.ccsp.device.bean.SessionKeyContext;
|
|
|
+import com.ccsp.device.crypto.CryptoException;
|
|
|
+import com.ccsp.device.crypto.SDFCrypto;
|
|
|
+import com.sansec.jcajce.provider.asymmetric.sm2.JCESM2PublicKey;
|
|
|
+import com.sansec.jce.provider.SwxaProvider;
|
|
|
+import com.sansec.util.BigIntegerUitl;
|
|
|
+
|
|
|
+import java.io.ByteArrayInputStream;
|
|
|
+import java.io.InputStream;
|
|
|
+import java.io.RandomAccessFile;
|
|
|
+import java.io.UnsupportedEncodingException;
|
|
|
+import java.security.Security;
|
|
|
+import java.security.cert.CertificateFactory;
|
|
|
+import java.security.cert.X509Certificate;
|
|
|
+import java.util.concurrent.CancellationException;
|
|
|
+
|
|
|
+public class Operation {
|
|
|
+
|
|
|
+ static SDFCrypto crypto;
|
|
|
+ static SDFCrypto crypto2;
|
|
|
+ //通过默认配置文件去初始化连接,如果配置文件位于接口库当前路径,参数传空即可。
|
|
|
+ static String filepath = "";
|
|
|
+
|
|
|
+ static String ip = "32.2.10.15"; // 公网环境:ip:60.217.194.220 端口:34012
|
|
|
+ static int port = 18007;
|
|
|
+ static String appName = "mhxfyjpt";
|
|
|
+ static String password = "mhxf@1234";
|
|
|
+ static String sm4keyid = "mhxfyjpt_SM4_Random_DEK";
|
|
|
+ static String sm2Keyid = "mhxfyjpt_SM2_Standard";
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ static int algo_hash = GlobalData.SGD_SM3;
|
|
|
+ static int algo_cbc = GlobalData.SGD_SM4_CBC;
|
|
|
+ static int algo_ecb = GlobalData.SGD_SM4_ECB;
|
|
|
+ static int algo_mac = GlobalData.SGD_SM4_MAC;
|
|
|
+
|
|
|
+ static int block_MB = 1*1024*1024;
|
|
|
+ static int block_50MB = block_MB*50;
|
|
|
+
|
|
|
+ static int block_KB=1*1024;
|
|
|
+ static int block_10KB = block_MB*10;
|
|
|
+ //
|
|
|
+ public Operation() {
|
|
|
+ try {
|
|
|
+ Security.addProvider(new SwxaProvider(null,null));
|
|
|
+ crypto = SDFFactory.getInstance(ip , port , 40, 30, 1);
|
|
|
+ crypto.SDF_LoginbyAppNameAndPwd(appName, password);
|
|
|
+ } catch (CryptoException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //对文件进行完整性计算
|
|
|
+ public String SM3AndCMAC(String file){
|
|
|
+ FileTools fileTool = new FileTools();
|
|
|
+ //获取文件大小
|
|
|
+ long fileSize = fileTool.getFileSize(file);
|
|
|
+ if (fileSize<=0) {
|
|
|
+ throw new RuntimeException("SM3AndCMAC error:"+"fileSize error");
|
|
|
+ }
|
|
|
+ RandomAccessFile rafr;
|
|
|
+ Object hashContext = null;
|
|
|
+ byte[] hash = null;
|
|
|
+ //组数
|
|
|
+ int groupNumber = 0;
|
|
|
+ //余数
|
|
|
+ int remainder = 0;
|
|
|
+ byte[] mac = null;
|
|
|
+ byte[] mac2=null;
|
|
|
+
|
|
|
+ groupNumber = (int)(fileSize/block_50MB);
|
|
|
+ remainder = (int)(fileSize%block_50MB);
|
|
|
+ String macValue = "";
|
|
|
+ String macValue2 = "";
|
|
|
+ try {
|
|
|
+ //read init
|
|
|
+ rafr = new RandomAccessFile(file, "r");
|
|
|
+ //开始sm3计算
|
|
|
+ hashContext = crypto.SDF_HashInit(algo_hash, null,null);
|
|
|
+ for (int i = 0; i < groupNumber; i++) {
|
|
|
+ crypto.SDF_HashUpdate(hashContext, fileTool.readFileByRAF(rafr, i*block_50MB, block_50MB));
|
|
|
+ }
|
|
|
+ if (remainder==0) {
|
|
|
+ hash = crypto.SDF_HashFinal(hashContext,null);
|
|
|
+ }else {
|
|
|
+ hash = crypto.SDF_HashFinal(hashContext,fileTool.readFileByRAF(rafr, groupNumber*block_50MB, remainder));
|
|
|
+ }
|
|
|
+ //开始CBCMAC计算
|
|
|
+ SessionKeyContext skc = new SessionKeyContext();
|
|
|
+ skc.setKeyID(sm4keyid.getBytes());
|
|
|
+ mac = crypto.SDF_CalculateMAC(skc, algo_mac, null, hash);
|
|
|
+ macValue = new String(Base64.encode(mac));
|
|
|
+
|
|
|
+ //end...
|
|
|
+ rafr.close();
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new RuntimeException("SM3AndCMAC error:"+e.getMessage());
|
|
|
+ }
|
|
|
+ return macValue;
|
|
|
+ }
|
|
|
+
|
|
|
+ //对文件进行机密性运算,输出密文文件
|
|
|
+ //sm4cbc加密
|
|
|
+ public void SM4CBCEnc(String originalFile,String encryptFile){
|
|
|
+ RandomAccessFile rafr;
|
|
|
+ RandomAccessFile rafw;
|
|
|
+ FileTools fileTool = new FileTools();
|
|
|
+ // 使用keyName构造key对象
|
|
|
+ SessionKeyContext skc = new SessionKeyContext();
|
|
|
+ skc.setKeyID(sm4keyid.getBytes());
|
|
|
+ try {
|
|
|
+ //read init
|
|
|
+ rafr = new RandomAccessFile(originalFile, "r");
|
|
|
+ byte[] tempEncdata = null;
|
|
|
+ byte[] inData = null;
|
|
|
+ byte[] inDataPading = null;
|
|
|
+ //组数
|
|
|
+ int groupNumber = 0;
|
|
|
+ //余数
|
|
|
+ int remainder = 0;
|
|
|
+ //获取文件大小
|
|
|
+ long fileSize = fileTool.getFileSize(originalFile);
|
|
|
+ if (fileSize<=0) {
|
|
|
+ throw new RuntimeException("SM4CBCEnc error:"+"fileSize error");
|
|
|
+ }
|
|
|
+ groupNumber = (int)(fileSize/block_50MB);
|
|
|
+ remainder = (int)(fileSize%block_50MB);
|
|
|
+ //创建临时的密文文件
|
|
|
+ String tempFile = encryptFile+".temp";
|
|
|
+ fileTool.creatFile(tempFile, fileSize+(16-remainder%16));
|
|
|
+ //writ init
|
|
|
+ rafw = new RandomAccessFile(tempFile, "rw");
|
|
|
+
|
|
|
+ //开始加密
|
|
|
+ for (int i = 0; i < groupNumber; i++) {
|
|
|
+ inData = fileTool.readFileByRAF(rafr,i*block_50MB, block_50MB);
|
|
|
+ tempEncdata = crypto.SDF_Encrypt(skc, algo_cbc, null, inData);
|
|
|
+ fileTool.writFileByRAF(rafw, i*block_50MB, tempEncdata);
|
|
|
+ }
|
|
|
+ inData = null;
|
|
|
+ inData = fileTool.readFileByRAF(rafr,groupNumber*block_50MB, remainder);
|
|
|
+ inDataPading = cbcPadding(inData);
|
|
|
+ tempEncdata = crypto.SDF_Encrypt(skc, algo_cbc, null, inDataPading);
|
|
|
+ fileTool.writFileByRAF(rafw, groupNumber*block_50MB, tempEncdata);
|
|
|
+
|
|
|
+ //end...
|
|
|
+ rafr.close();
|
|
|
+ rafw.close();
|
|
|
+ //改临时密文文件的名字
|
|
|
+ fileTool.reName(tempFile, encryptFile);
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new RuntimeException("SM4CBCEnc error:"+e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //sm4cbc解密
|
|
|
+ public void SM4CBCDec(String encryptFile, String decryptFile){
|
|
|
+ RandomAccessFile rafr;
|
|
|
+ RandomAccessFile rafw;
|
|
|
+ FileTools fileTool = new FileTools();
|
|
|
+
|
|
|
+ // 使用keyName构造key对象
|
|
|
+ SessionKeyContext skc = new SessionKeyContext();
|
|
|
+ skc.setKeyID(sm4keyid.getBytes());
|
|
|
+
|
|
|
+
|
|
|
+ try {
|
|
|
+ //read init
|
|
|
+ rafr = new RandomAccessFile(encryptFile, "r");
|
|
|
+
|
|
|
+
|
|
|
+ byte[] tempDecdata = null;
|
|
|
+ byte[] tempDecdataUnPading = null;
|
|
|
+ byte[] inData = null;
|
|
|
+
|
|
|
+ //组数
|
|
|
+ int groupNumber = 0;
|
|
|
+ //余数
|
|
|
+ int remainder = 0;
|
|
|
+ //原文文件大小
|
|
|
+ int decryptFileSize = 0;
|
|
|
+ String tempFile = decryptFile+".temp";
|
|
|
+ //获取文件大小
|
|
|
+ long fileSize = fileTool.getFileSize(encryptFile);
|
|
|
+ if (fileSize<=0) {
|
|
|
+ rafr.close();
|
|
|
+ throw new RuntimeException("SM4CBCDec error:"+"fileSize error");
|
|
|
+ }
|
|
|
+ groupNumber = (int)(fileSize/block_50MB);
|
|
|
+ remainder = (int)(fileSize%block_50MB);
|
|
|
+
|
|
|
+ //解最后的块
|
|
|
+ if (remainder!=0) {
|
|
|
+ inData = fileTool.readFileByRAF(rafr,groupNumber*block_50MB, remainder);
|
|
|
+ tempDecdata = crypto.SDF_Decrypt(skc, algo_cbc, null, inData);
|
|
|
+ tempDecdataUnPading = cbcUnPadding(tempDecdata);
|
|
|
+ decryptFileSize = (int)(fileSize - (remainder-tempDecdataUnPading.length));
|
|
|
+
|
|
|
+ //创建临时的密文文件
|
|
|
+ fileTool.creatFile(tempFile, decryptFileSize);
|
|
|
+ //writ init
|
|
|
+ rafw = new RandomAccessFile(tempFile, "rw");
|
|
|
+ fileTool.writFileByRAF(rafw, groupNumber*block_50MB, tempDecdataUnPading);
|
|
|
+
|
|
|
+ }else {
|
|
|
+ inData = fileTool.readFileByRAF(rafr,(groupNumber-1)*block_50MB, block_50MB);
|
|
|
+ tempDecdata = crypto.SDF_Decrypt(skc, algo_cbc, null, inData);
|
|
|
+ tempDecdataUnPading = cbcUnPadding(tempDecdata);
|
|
|
+ decryptFileSize = (int)(fileSize - (block_50MB-tempDecdataUnPading.length));
|
|
|
+
|
|
|
+ //创建临时的密文文件
|
|
|
+ fileTool.creatFile(tempFile, decryptFileSize);
|
|
|
+ //writ init
|
|
|
+ rafw = new RandomAccessFile(tempFile, "rw");
|
|
|
+ fileTool.writFileByRAF(rafw, (groupNumber-1)*block_50MB, tempDecdataUnPading);
|
|
|
+ groupNumber--;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //开始解密
|
|
|
+ for (int i = 0; i < groupNumber; i++) {
|
|
|
+ inData = fileTool.readFileByRAF(rafr,i*block_50MB, block_50MB);
|
|
|
+ tempDecdata = crypto.SDF_Decrypt(skc, algo_cbc, null, inData);
|
|
|
+ fileTool.writFileByRAF(rafw, i*block_50MB, tempDecdata);
|
|
|
+ }
|
|
|
+
|
|
|
+ //end...
|
|
|
+ rafr.close();
|
|
|
+ rafw.close();
|
|
|
+ //改临时密文文件的名字
|
|
|
+ fileTool.reName(tempFile, decryptFile);
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new RuntimeException("SM4CBCDec error:"+e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ //CBCMAC-SM4计算
|
|
|
+ public String CBCMAC(byte[] inData){
|
|
|
+ SessionKeyContext skc = new SessionKeyContext();
|
|
|
+ skc.setKeyID(sm4keyid.getBytes());
|
|
|
+ byte[] mac = null;
|
|
|
+ byte[] paddingData = macPadding(inData);
|
|
|
+ try {
|
|
|
+ mac = crypto.SDF_CalculateMAC(skc, algo_mac, null, paddingData);
|
|
|
+ } catch (CryptoException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ String macValue = new String(Base64.encode(mac));
|
|
|
+ return macValue;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //Hmac计算 (测试)
|
|
|
+ public String HMAC(byte[] inData){
|
|
|
+ SessionKeyContext skc = new SessionKeyContext();
|
|
|
+ skc.setKeyID(sm4keyid.getBytes());
|
|
|
+ byte[] mac = null;
|
|
|
+ byte[] paddingData = macPadding(inData);
|
|
|
+ try {
|
|
|
+ mac = crypto.SDF_CalculateMAC(skc, algo_mac, null, paddingData);
|
|
|
+ } catch (CryptoException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ String macValue = new String(Base64.encode(mac));
|
|
|
+ return macValue;
|
|
|
+ }
|
|
|
+ //mac运算填充
|
|
|
+ public byte[] macPadding(byte[] inData) {
|
|
|
+ byte[] padData = {(byte)0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
|
|
+ int remainder = inData.length%16;//余数
|
|
|
+ int padLength = 16 - remainder;
|
|
|
+ byte[] indatapad = new byte[inData.length+padLength];
|
|
|
+ System.arraycopy(inData, 0, indatapad, 0, inData.length);
|
|
|
+ System.arraycopy(padData, 0, indatapad, inData.length, padLength);
|
|
|
+ return indatapad;
|
|
|
+ }
|
|
|
+ //sm4cbc加密
|
|
|
+ public String SM4CBCEnc(byte[] inData){
|
|
|
+
|
|
|
+ // 使用keyName构造key对象
|
|
|
+ SessionKeyContext skc = new SessionKeyContext();
|
|
|
+ skc.setKeyID(sm4keyid.getBytes());
|
|
|
+ byte[] inDataPadding = cbcPadding(inData);
|
|
|
+ byte[] encdata = null;
|
|
|
+ try {
|
|
|
+ encdata = crypto.SDF_Encrypt(skc, algo_cbc, null, inDataPadding);
|
|
|
+ } catch (CryptoException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ String encdataStr = new String(Base64.encode(encdata));
|
|
|
+ return encdataStr;
|
|
|
+ }
|
|
|
+ //sm4cbc解密
|
|
|
+ public byte[] SM4CBCDec(String encStr){
|
|
|
+ byte[] indata = Base64.decode(encStr.getBytes());
|
|
|
+ // 使用keyName构造key对象
|
|
|
+ SessionKeyContext skc = new SessionKeyContext();
|
|
|
+ skc.setKeyID(sm4keyid.getBytes());
|
|
|
+
|
|
|
+ byte[] data = null;
|
|
|
+ try {
|
|
|
+ data = crypto.SDF_Decrypt(skc, algo_cbc, null, indata);
|
|
|
+ } catch (CryptoException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ byte[] outdata = cbcUnPadding(data);
|
|
|
+ return outdata;
|
|
|
+ }
|
|
|
+ //sm4加密数据填充
|
|
|
+ public byte[] cbcPadding(byte[] inData) {
|
|
|
+ byte[] padData = null;
|
|
|
+ int remainder = inData.length%16;//余数
|
|
|
+ int padLength = 16 - remainder;
|
|
|
+ padData = new byte[padLength];
|
|
|
+ for (int i = 0; i < padLength; i++) {
|
|
|
+ padData[i] = (byte)padLength;
|
|
|
+ }
|
|
|
+ byte[] indatapad = new byte[inData.length+padLength];
|
|
|
+ System.arraycopy(inData, 0, indatapad, 0, inData.length);
|
|
|
+ System.arraycopy(padData, 0, indatapad, inData.length, padLength);
|
|
|
+ return indatapad;
|
|
|
+ }
|
|
|
+ //sm4解密数据去填充
|
|
|
+ public byte[] cbcUnPadding(byte[] inData) {
|
|
|
+ byte[] outData = null;
|
|
|
+ int outDataLength = 0;
|
|
|
+ int padLength = (int)inData[inData.length-1];//余数
|
|
|
+ if (padLength>16||padLength<1) {
|
|
|
+ throw new RuntimeException("cbcUnPadding error,Data error");
|
|
|
+ }
|
|
|
+ outDataLength = inData.length-padLength;
|
|
|
+ outData = new byte[outDataLength];
|
|
|
+ System.arraycopy(inData, 0, outData, 0, outDataLength);
|
|
|
+ return outData;
|
|
|
+ }
|
|
|
+ //SM2数字签名
|
|
|
+ public String sm2Sign(byte[] inData) {
|
|
|
+ byte[] hash = null;
|
|
|
+ byte[] signValue = null;
|
|
|
+ SM2refPublicKey refPublicKey = null;
|
|
|
+ try {
|
|
|
+ refPublicKey =crypto.SDF_ExportPublicKey_ECC(sm2Keyid);
|
|
|
+ Object hashContext = null;
|
|
|
+ hashContext = crypto.SDF_HashInit(algo_hash, refPublicKey, "1234567812345678".getBytes());//算法为SM3时,第二个参数签名者公钥对象有效
|
|
|
+ crypto.SDF_HashUpdate(hashContext, inData);
|
|
|
+ hash = crypto.SDF_HashFinal(hashContext,null);
|
|
|
+ SM2refSignature sm2signValue = crypto.SDF_InternalSign_ECC(sm2Keyid,hash);
|
|
|
+ signValue = sm2signValue.encode();
|
|
|
+ } catch (CryptoException e) {
|
|
|
+ throw new RuntimeException("sm2Sign error:"+e.getMessage());
|
|
|
+ }
|
|
|
+ return new String(Base64.encode(signValue));
|
|
|
+ }
|
|
|
+
|
|
|
+ private byte[] getPubkeyByCert(String certStr) {
|
|
|
+ X509Certificate cert = null;
|
|
|
+ byte[] certByte = Base64.decode(certStr);
|
|
|
+ InputStream stream = new ByteArrayInputStream(certByte);
|
|
|
+
|
|
|
+ CertificateFactory factory = null;
|
|
|
+ try {
|
|
|
+ factory = CertificateFactory.getInstance("X.509", "SwxaJCE");
|
|
|
+ cert = (X509Certificate) factory.generateCertificate(stream);
|
|
|
+ } catch (CancellationException e) {
|
|
|
+ System.out.println("解析证书失败" + e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ JCESM2PublicKey pubKey = (JCESM2PublicKey)cert.getPublicKey();
|
|
|
+ byte[] pubkey = new byte[132];
|
|
|
+ for (int i = 0; i < pubkey.length; i++) {
|
|
|
+ pubkey[i]= 0x00;
|
|
|
+ }
|
|
|
+ pubkey[1] = 0x01;
|
|
|
+ System.arraycopy(BigIntegerUitl.asUnsigned32ByteArray(pubKey.getW().getAffineX()),0,pubkey,36,32);
|
|
|
+ System.arraycopy(BigIntegerUitl.asUnsigned32ByteArray(pubKey.getW().getAffineY()),0,pubkey,100,32);
|
|
|
+ return pubkey;
|
|
|
+ }
|
|
|
+
|
|
|
+ public String getSerialNumberByCert(String certStr) {
|
|
|
+ X509Certificate cert = null;
|
|
|
+ byte[] certByte = Base64.decode(certStr);
|
|
|
+ InputStream stream = new ByteArrayInputStream(certByte);
|
|
|
+
|
|
|
+ CertificateFactory factory = null;
|
|
|
+ try {
|
|
|
+ factory = CertificateFactory.getInstance("X.509", "SwxaJCE");
|
|
|
+ cert = (X509Certificate) factory.generateCertificate(stream);
|
|
|
+ } catch (CancellationException e) {
|
|
|
+ System.out.println("解析证书失败" + e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ String serialNumber = cert.getSerialNumber().toString(16);
|
|
|
+ return serialNumber;
|
|
|
+ }
|
|
|
+
|
|
|
+ private byte[] signValueDerToGm(byte[] derSignvalue) {
|
|
|
+ byte[] gm = new byte[128];
|
|
|
+ byte[] r = new byte[32];
|
|
|
+ byte[] s = new byte[32];
|
|
|
+ int p = 0;
|
|
|
+ if (derSignvalue[p]==0x30) {
|
|
|
+ p=p+2;
|
|
|
+ if (derSignvalue[p]==0x02) {
|
|
|
+ p = p+1;
|
|
|
+ if (derSignvalue[p]==0x20) {
|
|
|
+ p = p+1;
|
|
|
+ System.arraycopy(derSignvalue, p, r,0,32);
|
|
|
+ p = p+32;
|
|
|
+ if (derSignvalue[p]==0x02) {
|
|
|
+ p = p+1;
|
|
|
+ if (derSignvalue[p]==0x20) {
|
|
|
+ p = p+1;
|
|
|
+ System.arraycopy(derSignvalue, p, s,0,32);
|
|
|
+ }else if (derSignvalue[p]==0x21) {
|
|
|
+ p = p+2;
|
|
|
+ System.arraycopy(derSignvalue, p, s,0,32);
|
|
|
+ }else {
|
|
|
+ throw new RuntimeException("signValueDerToGm error");
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ throw new RuntimeException("signValueDerToGm error");
|
|
|
+ }
|
|
|
+ }else if (derSignvalue[p]==0x21) {
|
|
|
+ p = p+2;
|
|
|
+ System.arraycopy(derSignvalue, p, r,0,32);
|
|
|
+ p = p+32;
|
|
|
+ if (derSignvalue[p]==0x02) {
|
|
|
+ p = p+1;
|
|
|
+ if (derSignvalue[p]==0x20) {
|
|
|
+ p = p+1;
|
|
|
+ System.arraycopy(derSignvalue, p, s,0,32);
|
|
|
+ }else if (derSignvalue[p]==0x21) {
|
|
|
+ p = p+2;
|
|
|
+ System.arraycopy(derSignvalue, p, s,0,32);
|
|
|
+ }else {
|
|
|
+ throw new RuntimeException("signValueDerToGm error");
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ throw new RuntimeException("signValueDerToGm error");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ throw new RuntimeException("signValueDerToGm error");
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ throw new RuntimeException("signValueDerToGm error");
|
|
|
+ }
|
|
|
+ for (int i = 0; i < gm.length; i++) {
|
|
|
+ gm[i]=0x00;
|
|
|
+ }
|
|
|
+
|
|
|
+ System.arraycopy(r, 0,gm,32,32);
|
|
|
+ System.arraycopy(s, 0,gm,96,32);
|
|
|
+
|
|
|
+
|
|
|
+ return gm;
|
|
|
+ }
|
|
|
+
|
|
|
+ //SM2数字验签
|
|
|
+ public boolean sm2VerByCert(byte[] inData,String signValue,String certStr ) {
|
|
|
+ boolean result = false;
|
|
|
+ byte[] hash = null;
|
|
|
+ byte signValueOne = signValue.getBytes()[0];
|
|
|
+ byte[] signValueByte = null;
|
|
|
+ if (signValueOne=='M') {
|
|
|
+ //将der转换成GM
|
|
|
+ signValueByte = signValueDerToGm(Base64.decode(signValue));
|
|
|
+ }else {
|
|
|
+ signValueByte = Base64.decode(signValue.getBytes());
|
|
|
+ }
|
|
|
+ byte[] pubkey = getPubkeyByCert(certStr);
|
|
|
+ SM2refSignature sm2refSignature = new SM2refSignature();
|
|
|
+ SM2refPublicKey refPublicKey = new SM2refPublicKey();
|
|
|
+ try {
|
|
|
+ refPublicKey.decode(pubkey);
|
|
|
+ sm2refSignature.decode(signValueByte);
|
|
|
+ Object hashContext = null;
|
|
|
+ hashContext = crypto.SDF_HashInit(algo_hash, refPublicKey, "1234567812345678".getBytes());//算法为SM3时,第二个参数签名者公钥对象有效
|
|
|
+ crypto.SDF_HashUpdate(hashContext, inData);
|
|
|
+ hash = crypto.SDF_HashFinal(hashContext,null);
|
|
|
+ result = crypto.SDF_ExternalVerify_ECC(refPublicKey, hash,sm2refSignature);
|
|
|
+ result = true;
|
|
|
+ } catch (CryptoException e) {
|
|
|
+ System.out.println("sm2Ver error:"+e.getMessage());
|
|
|
+ result = false;
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ //SM2数字验签
|
|
|
+ public boolean sm2Ver(byte[] inData,String signValue,String publickey ) {
|
|
|
+ boolean result = false;
|
|
|
+ byte[] hash = null;
|
|
|
+ byte[] signValueByte = Base64.decode(signValue.getBytes());
|
|
|
+ byte[] pubkeyByte = Base64.decode(publickey.getBytes());
|
|
|
+ SM2refSignature sm2refSignature = new SM2refSignature();
|
|
|
+ SM2refPublicKey refPublicKey = new SM2refPublicKey();
|
|
|
+ try {
|
|
|
+ refPublicKey.decode(pubkeyByte);
|
|
|
+ sm2refSignature.decode(signValueByte);
|
|
|
+ Object hashContext = null;
|
|
|
+ hashContext = crypto.SDF_HashInit(algo_hash, refPublicKey, "1234567812345678".getBytes());//算法为SM3时,第二个参数签名者公钥对象有效
|
|
|
+ crypto.SDF_HashUpdate(hashContext, inData);
|
|
|
+ hash = crypto.SDF_HashFinal(hashContext,null);
|
|
|
+ result = crypto.SDF_ExternalVerify_ECC(refPublicKey, hash,sm2refSignature);
|
|
|
+ } catch (CryptoException e) {
|
|
|
+ throw new RuntimeException("sm2Ver error:"+e.getMessage());
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ public boolean sm2SignVer() throws UnsupportedEncodingException {
|
|
|
+ byte[] inData = "修改某条业务数据xxx为yyy".getBytes("utf-8");
|
|
|
+ boolean result = false;
|
|
|
+ byte[] hash = null;
|
|
|
+ byte[] signValueByte = null; //= Base64.decode(signValue.getBytes());
|
|
|
+ byte[] pubkeyByte = null;//= Base64.decode(publickey.getBytes());
|
|
|
+ SM2refSignature sm2refSignature = new SM2refSignature();
|
|
|
+ SM2refPublicKey refPublicKey = new SM2refPublicKey();
|
|
|
+ try {
|
|
|
+ refPublicKey = crypto.SDF_ExportPublicKey_ECC(sm2Keyid);
|
|
|
+ Object hashContext = null;
|
|
|
+ hashContext = crypto.SDF_HashInit(algo_hash, refPublicKey, "1234567812345678".getBytes());//算法为SM3时,第二个参数签名者公钥对象有效
|
|
|
+ crypto.SDF_HashUpdate(hashContext, inData);
|
|
|
+ hash = crypto.SDF_HashFinal(hashContext,null);
|
|
|
+
|
|
|
+ sm2refSignature = crypto.SDF_InternalSign_ECC(sm2Keyid, hash);
|
|
|
+ System.out.println(new String(Base64.encode(refPublicKey.encode())));
|
|
|
+ System.out.println(new String(Base64.encode(sm2refSignature.encode())));
|
|
|
+ result = crypto.SDF_ExternalVerify_ECC(refPublicKey, hash,sm2refSignature);
|
|
|
+ } catch (CryptoException e) {
|
|
|
+ throw new RuntimeException("sm2Ver error:"+e.getMessage());
|
|
|
+ }
|
|
|
+ System.out.println("sm2SignVer 成功");
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ public String getSm2PublicKey() {
|
|
|
+ SM2refPublicKey refPublicKey = null;
|
|
|
+ try {
|
|
|
+ refPublicKey =crypto.SDF_ExportPublicKey_ECC(sm2Keyid);
|
|
|
+ } catch (CryptoException e) {
|
|
|
+ throw new RuntimeException("getSm2PublicKey error:"+e.getMessage());
|
|
|
+ }
|
|
|
+ return new String(Base64.encode(refPublicKey.encode()));
|
|
|
+ }
|
|
|
+
|
|
|
+}
|