diff --git a/pom.xml b/pom.xml
index b812d9f..faee038 100644
--- a/pom.xml
+++ b/pom.xml
@@ -76,6 +76,24 @@
+
+ org.bouncycastle
+ bcpkix-jdk15on
+ 1.65
+
+
+
+ org.bouncycastle
+ bcprov-jdk15on
+ 1.65
+
+
+
+ cn.hutool
+ hutool-all
+ 5.8.4.M1
+
+
diff --git a/src/main/java/org/bouncycastle/cms/SydCmsUtil.java b/src/main/java/org/bouncycastle/cms/SydCmsUtil.java
new file mode 100644
index 0000000..79f45ba
--- /dev/null
+++ b/src/main/java/org/bouncycastle/cms/SydCmsUtil.java
@@ -0,0 +1,139 @@
+package org.bouncycastle.cms;
+
+import com.sunyard.SydApiException;
+import org.bouncycastle.asn1.*;
+import org.bouncycastle.asn1.cms.ContentInfo;
+import org.bouncycastle.asn1.cms.EncryptedContentInfo;
+import org.bouncycastle.asn1.cms.OriginatorInfo;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+
+public class SydCmsUtil {
+
+ public static Object readContentInfo(
+ byte[] input) {
+ ASN1InputStream is = new ASN1InputStream(input);
+ Object v = null;
+ try {
+ v = is.readObject();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return v;
+ }
+
+
+ public static Map getEncryptedContentInfo(ASN1Encodable obj){
+ Mapmap = new HashMap();
+ ASN1Sequence seq = ASN1Sequence.getInstance(obj );
+ if (seq.size() < 2)
+ {
+ throw new IllegalArgumentException("Truncated Sequence Found");
+ }
+
+ ASN1ObjectIdentifier contentType = (ASN1ObjectIdentifier)seq.getObjectAt(0);
+ map.put( "contentType", contentType );
+
+ AlgorithmIdentifier contentEncryptionAlgorithm = AlgorithmIdentifier.getInstance(
+ seq.getObjectAt(1));
+
+ map.put( "contentEncryptionAlgorithm", contentEncryptionAlgorithm );
+
+ if (seq.size() > 2)
+ {
+ ASN1OctetString encryptedContent = ASN1OctetString.getInstance(
+ (ASN1TaggedObject)seq.getObjectAt(2), false);
+ map.put( "encryptedContent", encryptedContent );
+ }
+ return map;
+ }
+
+ public static Map getOriginatorInfo(ASN1TaggedObject obj,
+ boolean explicit){
+ Mapmap = new HashMap();
+ ASN1Sequence seq = ASN1Sequence.getInstance(obj, explicit);
+ switch (seq.size())
+ {
+ case 0: // empty
+ break;
+ case 1:
+ ASN1TaggedObject o = (ASN1TaggedObject)seq.getObjectAt(0);
+ switch (o.getTagNo())
+ {
+ case 0 :
+ ASN1Set certs = ASN1Set.getInstance(o, false);
+ map.put("certs", certs);
+ break;
+ case 1 :
+ ASN1Set crls = ASN1Set.getInstance(o, false);
+ map.put("crls", crls);
+ break;
+ default:
+ throw new IllegalArgumentException("Bad tag in OriginatorInfo: " + o.getTagNo());
+ }
+ break;
+ case 2:
+ ASN1Set certs = ASN1Set.getInstance((ASN1TaggedObject)seq.getObjectAt(0), false);
+ map.put("certs", certs);
+ ASN1Set crls = ASN1Set.getInstance((ASN1TaggedObject)seq.getObjectAt(1), false);
+ map.put("crls", crls);
+ break;
+ default:
+ throw new IllegalArgumentException("OriginatorInfo too big");
+ }
+
+ return map;
+ }
+
+ public static ContentInfo getContentInfo( byte[] input ) {
+ Object content = readContentInfo( input );
+ ASN1Sequence seq = ASN1Sequence.getInstance( content );
+ return new ContentInfo(seq);
+ }
+
+ public static Map readCmsInfo( byte[] input ) throws CMSException {
+ Mapmap = new HashMap();
+
+ Object content = readContentInfo( input );
+ ASN1Sequence seq = ASN1Sequence.getInstance( content );
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) seq.getObjectAt(0);
+ map.put("oid", oid);
+
+ seq = ASN1Sequence.getInstance((ASN1TaggedObject) seq.getObjectAt(1), true);
+
+ int index = 0;
+
+ ASN1Integer version = (ASN1Integer)seq.getObjectAt(index++);
+ map.put( "version", version );
+
+ Object tmp = seq.getObjectAt(index++);
+
+ if (tmp instanceof ASN1TaggedObject)
+ {
+ OriginatorInfo originatorInfo = OriginatorInfo.getInstance((ASN1TaggedObject)tmp, false);
+// MaporiginatorInfo = getOriginatorInfo((ASN1TaggedObject)tmp, false);
+ map.put( "originatorInfo", originatorInfo );
+ tmp = seq.getObjectAt(index++);
+ }
+
+ ASN1Set recipientInfos = ASN1Set.getInstance(tmp);
+ map.put( "recipientInfos", recipientInfos );
+
+ EncryptedContentInfo encryptedContentInfo = EncryptedContentInfo.getInstance( seq.getObjectAt(index++) );
+// Map encryptedContentInfo = getEncryptedContentInfo(seq.getObjectAt(index++));
+ map.put( "encryptedContentInfo", encryptedContentInfo );
+
+ if(seq.size() > index)
+ {
+ ASN1Set unprotectedAttrs = ASN1Set.getInstance((ASN1TaggedObject)seq.getObjectAt(index), false);
+ map.put( "unprotectedAttrs", unprotectedAttrs );
+ }
+
+ return map;
+ }
+
+}
diff --git a/src/main/java/racal/sunyard/main/SydApi4j.java b/src/main/java/racal/sunyard/main/SydApi4j.java
index 4f25bd6..25f73ed 100644
--- a/src/main/java/racal/sunyard/main/SydApi4j.java
+++ b/src/main/java/racal/sunyard/main/SydApi4j.java
@@ -1,5 +1,6 @@
package racal.sunyard.main;
+import cn.hutool.core.bean.BeanUtil;
import com.sunyard.RetWrap;
import com.sunyard.SYMEnDeLongData;
import com.sunyard.SydApi;
@@ -10,7 +11,6 @@ import com.sunyard.proto.Packet;
import com.sunyard.proto.PacketSection;
import com.sunyard.proto.Util;
import com.sunyard.proto.section.SectionValue;
-import com.sunyard.proto.value.Str;
import com.sunyard.trans.Alg;
import com.sunyard.trans.FullMode;
import com.sunyard.trans.PacketSN;
@@ -19,7 +19,18 @@ import com.sunyard.util.CoderUtil;
import com.sunyard.util.FileUtil;
import com.sunyard.util.MyUtil;
import com.sunyard.util.SYMUtil;
-import racal.sunyard.main.dto.*;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.ASN1Set;
+import org.bouncycastle.asn1.ASN1TaggedObject;
+import org.bouncycastle.asn1.DEROctetString;
+import org.bouncycastle.asn1.cms.ContentInfo;
+import org.bouncycastle.cms.SydCmsUtil;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
+import racal.sunyard.main.dto.DTO77;
+import racal.sunyard.main.dto.DTO78;
+import racal.sunyard.main.dto.DTO79;
+import racal.sunyard.main.dto.DTO7A;
import racal.sunyard.main.proto.*;
import java.io.*;
@@ -27,14 +38,22 @@ import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketTimeoutException;
-import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
+import java.security.NoSuchProviderException;
+import java.security.Security;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.*;
public class SydApi4j implements SydApi {
+ static {
+ Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
+ }
+
private static boolean debug = false;
private static long sTime = System.currentTimeMillis();
@@ -465,7 +484,7 @@ public class SydApi4j implements SydApi {
byte[] be = error.getBytes();
if ((0 != (be[0] ^ be[1]))) {
SydApiException e = new SydApiException(error.getInfo(), error.autoInt());
- println("验签失败=" + e.toString() );
+ println("验签失败=" + e.toString());
return false;
}
return true;
@@ -713,7 +732,7 @@ public class SydApi4j implements SydApi {
byte[] be = error.getBytes();
if ((0 != (be[0] ^ be[1]))) {
SydApiException e = new SydApiException(error.getInfo(), error.autoInt());
- println("验签失败=" + e.toString() );
+ println("验签失败=" + e.toString());
return false;
}
@@ -976,7 +995,6 @@ public class SydApi4j implements SydApi {
}
/**
- *
* @param certData
* @param organizationId
* @return
@@ -1916,10 +1934,11 @@ public class SydApi4j implements SydApi {
/**
* 对指定报文数据进行SM4加密
- * @param type 密钥类型。0: ZEK,1: TEK
+ *
+ * @param type 密钥类型。0: ZEK,1: TEK
* @param userId 生成密钥时的机构号。
- * @param index 密钥索引
- * @param data 待加密的数据
+ * @param index 密钥索引
+ * @param data 待加密的数据
* @return
*/
public byte[] SYMSM4EncDataByIndex(int type, String userId, String index, byte[] data) {
@@ -2057,13 +2076,14 @@ public class SydApi4j implements SydApi {
/**
* 对指定报文数据进行SM4解密
- * @param type 密钥类型。0: ZEK,1: TEK
- * @param userId 生成密钥时的机构号
- * @param index 密钥索引
+ *
+ * @param type 密钥类型。0: ZEK,1: TEK
+ * @param userId 生成密钥时的机构号
+ * @param index 密钥索引
* @param pINdata 要解密的报文密文。长度必须是8 或16 的倍数
* @return
*/
- public byte[] SYMSM4DecDataByIndex (int type, String userId, String index, byte[] pINdata) {
+ public byte[] SYMSM4DecDataByIndex(int type, String userId, String index, byte[] pINdata) {
if (userId.length() > 16 || index.length() > 8) {
throw new SydApiException("机构号或索引长度不匹配", -27);
@@ -2327,6 +2347,208 @@ public class SydApi4j implements SydApi {
return decryptDE(true, 1, dnBytes, pCipherKey);
}
+
+ /**
+ * 通过 DN 查找证书
+ *
+ * @param dn
+ * @return
+ */
+ public String getCertByDn(String dn) throws UnsupportedEncodingException {
+ byte[] dnBytes = null;
+ try {
+ dnBytes = dn.getBytes("gbk");
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ throw e;
+ }
+ return getCertByDn(dnBytes);
+ }
+
+ public String getCertByDn(byte[] dnBytes) {
+ // 8010 指令,没有指令配置文件
+
+ // head
+ PacketSN sn = PacketSN.gen();
+ HashMap packet = new HashMap();
+
+ // data
+ byte[] data = new byte[256];
+ Arrays.fill(data, (byte) 0);
+ System.arraycopy(dnBytes, 0, data, 0, dnBytes.length);
+
+ ByteBuffer bb = ByteBuffer.allocate(2 + 8 + 2 + data.length +1 );
+ // 2 报文总长
+ bb.put((byte) 0x01);
+ bb.put((byte) 0x0B);
+
+ // 8 SN
+ bb.put(sn.getSn().array());
+
+ // 2 CMD
+ bb.put((byte) 0x80);
+ bb.put((byte) 0x10);
+
+ // 256 Data
+ bb.put(data);
+
+ // 加密
+ bb.put((byte)0x31);
+
+ synchronized (this) {
+ // 响应解析
+ bb = syncRead(syncSend(bb));
+ }
+
+ byte[] success = new byte[2];
+ Arrays.fill(success, (byte) 0);
+
+ byte[] ret = new byte[2];
+ bb.position(12);
+ bb.get(ret);
+
+ if (!Arrays.equals(ret, success)) {
+ throw new SydApiException("获取证书异常", ret[0] * 256 + ret[1]);
+ }
+
+ byte[] len = new byte[2];
+ bb.get(len);
+
+ int l = len[0] * 256 + len[1];
+ byte[] cert = new byte[l];
+ bb.get(cert);
+
+ return new String(cert);
+ }
+
+ public static X509Certificate getX509Certificate(InputStream is) throws CertificateException,
+ NoSuchProviderException {
+ CertificateFactory cf = CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME);
+ return (X509Certificate) cf.generateCertificate(is);
+ }
+
+ public RetWrap generateDEByDnSoft(String certSerial, String oData) {
+ RetWrap ret = new RetWrap();
+ byte[] dnBytes = null;
+ try {
+ dnBytes = certSerial.getBytes("gbk");
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+
+ // 查询完整证书
+ String cert = getCertByDn(dnBytes);
+ println("cert=" + cert);
+
+ try {
+ X509Certificate x509 = getX509Certificate(new ByteArrayInputStream(cert.getBytes()));
+
+ String pk = ByteUtils.toHexString(x509.getPublicKey().getEncoded());
+ if (!pk.startsWith("03420004")) {
+ int i = pk.indexOf("03420004");
+ if ( i >= 0 ) {
+ pk = pk.substring(i);
+ } else {
+ pk = "03420004" + pk;
+ }
+ }
+
+
+ // 生成会话密钥
+ ret = SM2GenSessionKey(pk);
+ String ciperKey = ret.get(SydApi.RET_CIPHER_KEY).toString();
+ String sessionKeyByLMK = ret.get(SydApi.RET_SESSION_KEY).toString();
+
+ println("ciperKey=" + ciperKey);
+
+ // 加密数据
+ byte[] iv = new byte[32];
+ Arrays.fill(iv, (byte) 0x30);
+ RetWrap retWrap = SYMEnDeData(true, 1, sessionKeyByLMK, 1, 1, oData.getBytes(), iv, 0);
+ byte[] enData = (byte[]) retWrap.get("msg_all");
+
+ // 组织格式
+ ContentInfo cms = genCMSEnvelopedData(Util.hexString2Bytes(ciperKey), enData);
+
+ ret.put(SydApi.RET_CIPHER_KEY, Util.encodeBase64(cms.getEncoded()));
+
+ return ret;
+
+ } catch (SydApiException syde) {
+ throw syde;
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new SydApiException("生成数字信封错误", -5);
+ }
+ }
+
+// private RetWrap deCMSEnvelopedData(byte[] cms) throws CMSException {
+// RetWrap ret = new RetWrap();
+// ContentInfo info = SydCmsUtil.getContentInfo( cms );
+// // 修改
+// ASN1Sequence seq = (ASN1Sequence) info.getContent().toASN1Primitive();
+//
+// ASN1Set set = ASN1Set.getInstance(seq.getObjectAt(1).toASN1Primitive());
+// ASN1Sequence seq2 = (ASN1Sequence) set.getObjectAt( 0 ).toASN1Primitive();
+//
+// // 会话密钥
+// DEROctetString key = (DEROctetString) seq2.getObjectAt( 3 );
+// ret.put("sessionKeyDer", key.getOctets() );
+//
+// // 密文段
+// ASN1Sequence seq5 = (ASN1Sequence) seq.getObjectAt( 2 ).toASN1Primitive();
+// ASN1TaggedObject tag = (ASN1TaggedObject) seq5.getObjectAt(2).toASN1Primitive();
+// DEROctetString data = (DEROctetString) tag.getObject();
+// ret.put("enData", data.getOctets() );
+// return ret;
+// }
+
+ public static ContentInfo genCMSEnvelopedData(byte[] sessionKeyDer, byte[] enData) {
+ String tmpl = "3082014D06092A864886F70D010703A082013E3082013A0201003181F73081F40201003065305C310B300906035504061302434E3130302E060355040A0C274368696E612046696E616E6369616C2043657274696669636174696F6E20417574686F72697479311B301906035504030C1243464341205445535420534D32204F43413102051004282452300B06092A811CCF5501822D03047B307902203C3AF535307DA548DA02C0AD171D2BC24D22472B42E5E175FCAF2C5CD30B5443022100ED53E7594F35FFACEB57F05898123F78E5B2D045CC47D894CD2E7BD34D66DA1D042014BD71F8CDA9729093A7CC391E2009C5D5F007586C2EBFB55BC175A6E8BDA33E04104AB82510BFDDD4FEE79C3F107D6F7F94303B060A2A811CCF550601040201301B06072A811CCF55016804100000000000000000000000000000000080109FD3D4338DB19E672CC162AF5B9B03E9";
+ ContentInfo info = SydCmsUtil.getContentInfo(Util.hexString2Bytes(tmpl));
+ // 修改
+ ASN1Sequence seq = (ASN1Sequence) info.getContent().toASN1Primitive();
+
+ ASN1Set set = ASN1Set.getInstance(seq.getObjectAt(1).toASN1Primitive());
+ ASN1Sequence seq2 = (ASN1Sequence) set.getObjectAt(0).toASN1Primitive();
+
+ // 会话密钥
+ DEROctetString key = (DEROctetString) seq2.getObjectAt(3);
+ BeanUtil.setFieldValue(key, "string", sessionKeyDer);
+
+ // 签发信息段
+ ASN1Sequence seq3 = (ASN1Sequence) seq2.getObjectAt(1).toASN1Primitive();
+ System.out.println(seq3);
+
+ // 密文段
+ ASN1Sequence seq4 = (ASN1Sequence) seq.getObjectAt(2).toASN1Primitive();
+ ASN1TaggedObject tag = (ASN1TaggedObject) seq4.getObjectAt(2).toASN1Primitive();
+ DEROctetString data = (DEROctetString) tag.getObject();
+ BeanUtil.setFieldValue(data, "string", enData);
+ return info;
+ }
+
+ public RetWrap decryptDEByDNSoft(String certSerial, String pCipherKey) {
+ byte[] dnBytes = null;
+ try {
+ dnBytes = certSerial.getBytes("gbk");
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+
+// RetWrap ret = deCMSEnvelopedData( Util.decodeBase64( pCipherKey ) );
+
+ // 解密会话密钥
+
+ decryptDE(false, 1, dnBytes, pCipherKey);
+
+ // 解密原文
+
+
+ return null;
+ }
+
+
// 测试通过
@Override
public RetWrap decryptDE(boolean pFlag, int model, byte[] certSerial, String pCipherKey) {
@@ -2434,9 +2656,10 @@ public class SydApi4j implements SydApi {
/**
* 用指定的证书私钥对指定的数据进行数字签名。
* 银联
+ *
* @param pCertSerial 输入。签名 X509 证书的序列号。
- * @param userId 输入。用户id。
- * @param pOrgData 输入。 待签名的原始数据。
+ * @param userId 输入。用户id。
+ * @param pOrgData 输入。 待签名的原始数据。
* @return 签名数据(BASE64 编码)。
*/
@Override
@@ -2447,7 +2670,7 @@ public class SydApi4j implements SydApi {
Proto6C proto = new Proto6C();
// 先进行 HASH
- pOrgData = SM3HashSNaId(pCertSerial, userId, pOrgData );
+ pOrgData = SM3HashSNaId(pCertSerial, userId, pOrgData);
// 填充数据
PacketSN sn = PacketSN.gen();
@@ -2487,18 +2710,19 @@ public class SydApi4j implements SydApi {
/**
* 用指定证书对指定的原始数据进行数字签名验证。
* 银联
+ *
* @param pCertSerial 输入。 签名 X509 证书的序列号。
- * @param userId 输入。用户id。
- * @param pOrgData 输入。 待签名的原始数据。
- * @param pSignData 输入。 签名数据(BASE64 编码)。
+ * @param userId 输入。用户id。
+ * @param pOrgData 输入。 待签名的原始数据。
+ * @param pSignData 输入。 签名数据(BASE64 编码)。
* @return true 表示验证正确;false 表示失败;
*/
@Override
public boolean unPVerify(String pCertSerial, String userId, byte[] pOrgData, String pSignData) {
// 获取协议
- Proto6D proto=new Proto6D();
+ Proto6D proto = new Proto6D();
- pOrgData = SM3HashSNaId(pCertSerial, userId, pOrgData );
+ pOrgData = SM3HashSNaId(pCertSerial, userId, pOrgData);
// 填充数据
PacketSN sn = PacketSN.gen();
@@ -2516,7 +2740,7 @@ public class SydApi4j implements SydApi {
ByteBuffer bb = proto.rend(packet);
synchronized (this) {
// 响应解析
- bb = syncRead( syncSend(bb) );
+ bb = syncRead(syncSend(bb));
}
//ProtocolParser parser = pset.getProtocolResParse();
Packet p = proto.parse(bb);
@@ -2538,8 +2762,9 @@ public class SydApi4j implements SydApi {
/**
* 用指定的证书私钥对指定的数据进行数字签名。
* 网联
+ *
* @param pCertSerial 输入。签名 X509 证书的序列号。
- * @param pOrgData 输入。 待签名的原始数据。
+ * @param pOrgData 输入。 待签名的原始数据。
* @return 签名数据(BASE64 编码)。
*/
@Override
@@ -2550,7 +2775,7 @@ public class SydApi4j implements SydApi {
Proto6C proto = new Proto6C();
// 先进行 HASH
- pOrgData = SM3HashSNaId( pCertSerial, null, pOrgData );
+ pOrgData = SM3HashSNaId(pCertSerial, null, pOrgData);
// 填充数据
PacketSN sn = PacketSN.gen();
@@ -2590,18 +2815,19 @@ public class SydApi4j implements SydApi {
/**
* 用指定证书对指定的原始数据进行数字签名验证。
* 网联
+ *
* @param pCertSerial 输入。 签名 X509 证书的序列号。
- * @param pOrgData 输入。 待签名的原始数据。
- * @param pSignData 输入。 签名数据(BASE64 编码)。
+ * @param pOrgData 输入。 待签名的原始数据。
+ * @param pSignData 输入。 签名数据(BASE64 编码)。
* @return true 表示验证正确;false 表示失败;
*/
@Override
public boolean netVerify(String pCertSerial, byte[] pOrgData, String pSignData) {
// 获取协议
//ProtocolRender render = pset.getProtocolReqRender("6D");
- Proto6D proto=new Proto6D();
+ Proto6D proto = new Proto6D();
- pOrgData = SM3HashSNaId( pCertSerial, null, pOrgData );
+ pOrgData = SM3HashSNaId(pCertSerial, null, pOrgData);
// 填充数据
PacketSN sn = PacketSN.gen();
@@ -2619,7 +2845,7 @@ public class SydApi4j implements SydApi {
ByteBuffer bb = proto.rend(packet);
synchronized (this) {
// 响应解析
- bb = syncRead( syncSend(bb) );
+ bb = syncRead(syncSend(bb));
}
//ProtocolParser parser = pset.getProtocolResParse();
Packet p = proto.parse(bb);
@@ -3144,6 +3370,7 @@ public class SydApi4j implements SydApi {
/**
* 通过密钥索引获得 SM2 公钥(DER 编码)。
+ *
* @param privateKeyTag 指示用户密钥存储区的27位地址,27位的索引号:16位机构号+3位密钥类型+8位密钥索引号
* @return 公钥数据的der编码
*/
@@ -3228,6 +3455,7 @@ public class SydApi4j implements SydApi {
/**
* 导出一个SM2私钥。
+ *
* @param privateKeyTag 要导出密钥的索引,27位的索引号:16位机构号+3位密钥类型+8位密钥索引号
* @return LMK下加密的私钥
*/
@@ -3391,7 +3619,8 @@ public class SydApi4j implements SydApi {
/**
* 通过SN获取证书信息
- * @param sn sn
+ *
+ * @param sn sn
* @param nCertType 证书类型,0:签名证书, 1:加密证书
* @return
*/
@@ -3408,8 +3637,9 @@ public class SydApi4j implements SydApi {
/**
* 通过sn或机构号获取证书
- * @param flag 0: SN,1: 机构号
- * @param userId 根据flag确定传入的数据
+ *
+ * @param flag 0: SN,1: 机构号
+ * @param userId 根据flag确定传入的数据
* @param nCertType 证书类型,0:签名证书, 1:加密证书
* @return
*/
@@ -3472,15 +3702,16 @@ public class SydApi4j implements SydApi {
* 用户id默认为1234567812345678
* 签名结果R/S序列串先进行der编码,再进行base64编码
*
- * @param flag 私钥标志位,当为1时第二个参数传入存储私钥的索引,当为0时第二个参数传入私钥
+ * @param flag 私钥标志位,当为1时第二个参数传入存储私钥的索引,当为0时第二个参数传入私钥
* @param privateKey 当私钥标志位为1时传入存储私钥的索引,当为0时传入私钥
- * @param publicKey 公钥
- * @param orgData 要签名的信息
+ * @param publicKey 公钥
+ * @param orgData 要签名的信息
* @return 签名结果
*/
public String SM2SignC(int flag, String privateKey, byte[] publicKey, byte[] orgData) {
- return SM2SignC( flag, "1234567812345678", privateKey, publicKey, orgData);
+ return SM2SignC(flag, "1234567812345678", privateKey, publicKey, orgData);
}
+
// 测试通过
@Override
public String SM2SignC(int flag, String uid, String privateKey, byte[] publicKey, byte[] orgData) {
@@ -3532,8 +3763,8 @@ public class SydApi4j implements SydApi {
* sm2验签
* 用户id默认为1234567812345678
*
- * @param publicKey 公钥的 DER 编码
- * @param orgData 签名信息
+ * @param publicKey 公钥的 DER 编码
+ * @param orgData 签名信息
* @param base64Sign 计算的签名,签名结果R/S序列串先进行der编码,再进行base64编码后的结果
* @return true 验签成功,false 验签失败
*/
@@ -3701,7 +3932,7 @@ public class SydApi4j implements SydApi {
byte[] publicKey,
byte[] orgData,
String base64Sign
- ){
+ ) {
String certNo = "1234567812345678";
return SM2Verify(certNo, nOrgDataType, publicKey, orgData, base64Sign);
}
@@ -3854,8 +4085,9 @@ public class SydApi4j implements SydApi {
/**
* 用私钥加密数据
- * @param alg 算法标识,0:RSA 1:SM2
- * @param sk 指示私钥位置的标记,数字为存储私钥的索引,除了全 9 表示使用由命令中提供的密钥。
+ *
+ * @param alg 算法标识,0:RSA 1:SM2
+ * @param sk 指示私钥位置的标记,数字为存储私钥的索引,除了全 9 表示使用由命令中提供的密钥。
* @param data 数据
* @return 密文的 DER 编码(对于 RSA 算法,数据类型为 BIT).
*/
@@ -3894,8 +4126,9 @@ public class SydApi4j implements SydApi {
/**
* 用公钥解密数据
- * @param alg 算法标识,0:RSA 1:SM2
- * @param pk 公钥的 DER 编码
+ *
+ * @param alg 算法标识,0:RSA 1:SM2
+ * @param pk 公钥的 DER 编码
* @param data 数据
* @return 明文
*/
@@ -3967,8 +4200,9 @@ public class SydApi4j implements SydApi {
/**
* 非对称公钥加密
- * @param alg 算法标识,0 = RSA 1 = SM2
- * @param pk 公钥的 DER 编码
+ *
+ * @param alg 算法标识,0 = RSA 1 = SM2
+ * @param pk 公钥的 DER 编码
* @param data 数据
* @return 公钥加密的密文的 DER 编码(对于 RSA 算法,数据类型为 BIT).
*/
@@ -3978,8 +4212,9 @@ public class SydApi4j implements SydApi {
/**
* 非对称私钥解密
- * @param alg 算法标识:0 = RSA 1 = SM2
- * @param sk 私钥值,LMK下加密的私钥
+ *
+ * @param alg 算法标识:0 = RSA 1 = SM2
+ * @param sk 私钥值,LMK下加密的私钥
* @param data 密文数据(DER 编码)
* @return 公钥加密的密文的 DER 编码(对于 RSA 算法,数据类型为 BIT)
*/
@@ -4332,8 +4567,9 @@ public class SydApi4j implements SydApi {
/**
* 通过使用者 ID 所对应的私钥对指定的密文数据进行解密。
* 输入的sm2密文结构为C1C2C3格式
+ *
* @param userId 使用者的 ID,最大长度为 16 位数字,右对齐。
- * @param enData 加密的数据,base64 编码。
+ * @param enData 加密的数据,base64 编码。
* @param keyType 密钥类型,0:签名证书, 1:加密证书。
* @return 明文数据。
*/
@@ -4382,11 +4618,12 @@ public class SydApi4j implements SydApi {
/**
* 计算SM3散列值
+ *
* @param publicKey 公钥的 DER 编码(可以为空)
- * @param csn 证书序号
- * @param cdn 证书DN
- * @param userId 用户ID
- * @param msg 原始数据,二进制的消息块
+ * @param csn 证书序号
+ * @param cdn 证书DN
+ * @param userId 用户ID
+ * @param msg 原始数据,二进制的消息块
* @return
*/
private byte[] SM3Hash(String publicKey, String csn, String cdn, String userId, byte[] msg) {
@@ -4438,7 +4675,7 @@ public class SydApi4j implements SydApi {
if ('0' == packtype || '1' == packtype) {
- if ( null != csn || null != cdn ){
+ if (null != csn || null != cdn) {
if (userId != null) {
bb.put(String.format("%02d", userId.length()).getBytes());
bb.put(userId.getBytes());
@@ -4450,18 +4687,17 @@ public class SydApi4j implements SydApi {
// 通过证书查找公钥
bb.put("P".getBytes());
byte[] content;
- if ( null != csn ){
+ if (null != csn) {
content = csn.getBytes();
- bb.put( "0".getBytes() );
+ bb.put("0".getBytes());
} else {
content = cdn.getBytes();
- bb.put( "1".getBytes() );
+ bb.put("1".getBytes());
}
- bb.put( String.format("%04d", content.length ).getBytes() );
- bb.put( content );
- }
- else if (null == publicKey) {
+ bb.put(String.format("%04d", content.length).getBytes());
+ bb.put(content);
+ } else if (null == publicKey) {
// 无公钥
@@ -4469,8 +4705,7 @@ public class SydApi4j implements SydApi {
bb.put("".getBytes());
bb.put(String.format("%04d", 0).getBytes());
bb.put("".getBytes());
- }
- else {
+ } else {
// 传入公钥
bb.put(String.format("%02d", 16).getBytes());
bb.put("1234567812345678".getBytes());
@@ -4555,7 +4790,6 @@ public class SydApi4j implements SydApi {
}
-
@Override
public byte[] SM3Hash(String publicKey, byte[] msg, int block, byte[] mac) {
@@ -4797,9 +5031,10 @@ public class SydApi4j implements SydApi {
/**
* 数字信封加密数据 会员定制格式
- * @param keyValue 公钥值
+ *
+ * @param keyValue 公钥值
* @param inPutDataStr 报文明文
- * @param msgId 设备认证内容
+ * @param msgId 设备认证内容
* @return 格式:sessionByPk(base64)+\r\n+头(base64)+\r\n+密文(base64)
* @throws UnsupportedEncodingException
*/
@@ -4973,11 +5208,12 @@ public class SydApi4j implements SydApi {
* 使用SM4算法进行加密,其中加密模式为CBC,
* Ⅳ使用缺省值0X 00000000000000000000000000000000,
* 补位模式为 PKCS5 PADDING 。
- * @param keyType 密钥类型 0: ZEK,1: TEK
- * @param key 密钥
- * @param inType 输入消息类型 0:二进制 1:扩展十六进制
- * @param outType 输出消息类型 0:二进制 1:扩展十六进制
- * @param inFilePath 需要加密的数据文件所在的路径
+ *
+ * @param keyType 密钥类型 0: ZEK,1: TEK
+ * @param key 密钥
+ * @param inType 输入消息类型 0:二进制 1:扩展十六进制
+ * @param outType 输出消息类型 0:二进制 1:扩展十六进制
+ * @param inFilePath 需要加密的数据文件所在的路径
* @param outFilePath 加密后的密文数据将要保存的文件路径
* @return 加密是否成功。false为失败,true为成功
*/
@@ -5011,21 +5247,21 @@ public class SydApi4j implements SydApi {
File in = new File(inFilePath);
- if ( !in.exists() ){
+ if (!in.exists()) {
throw new SydApiException("要加密的文件不存在", -27);
}
long length = in.length();
int l = new Long(length).intValue();
- int n = l / ( 2 * 1024);
- println("n 个 2k:"+n);
+ int n = l / (2 * 1024);
+ println("n 个 2k:" + n);
- if (l % ( 2 * 1024) != 0) {
+ if (l % (2 * 1024) != 0) {
n++;
}
File out = new File(outFilePath);
- if ( out.exists() ){
+ if (out.exists()) {
out.delete();
}
try {
@@ -5033,34 +5269,34 @@ public class SydApi4j implements SydApi {
} catch (IOException e) {
e.printStackTrace();
}
- BufferedInputStream fis =null;
- BufferedOutputStream fos=null;
+ BufferedInputStream fis = null;
+ BufferedOutputStream fos = null;
try {
fis = new BufferedInputStream(new FileInputStream(in));
fos = new BufferedOutputStream(new FileOutputStream(out));
byte[] buff = new byte[2 * 1024];
- for (int i = 0; i < n-1; i++) {
- int len = fis.read( buff );
+ for (int i = 0; i < n - 1; i++) {
+ int len = fis.read(buff);
//先判断是否是最后一块/唯一块,是->calc,
//首块和中间块才->update
- if ( len == buff.length){
- println("len长度_update:"+len);
- byte[] en = sym.update( buff );
- println("en长度:"+en.length);
- fos.write( en );
+ if (len == buff.length) {
+ println("len长度_update:" + len);
+ byte[] en = sym.update(buff);
+ println("en长度:" + en.length);
+ fos.write(en);
}
}
- int len = fis.read( buff );
+ int len = fis.read(buff);
//先判断是否是最后一块/唯一块,是->calc,
//首块和中间块才->update
- if ( len <= buff.length && len>-1) {
+ if (len <= buff.length && len > -1) {
println("len长度_calc:" + len);
byte[] en = sym.calc(buff, len);
println("en长度:" + en.length);
- fos.write( en );
+ fos.write(en);
}
} catch (IOException e) {
e.printStackTrace();
@@ -5094,14 +5330,15 @@ public class SydApi4j implements SydApi {
* 使用SM4算法进行加密,其中加密模式为CBC,
* Ⅳ使用缺省值0X 00000000000000000000000000000000,
* 补位模式为 PKCS5 PADDING 。
- * @param isEn 是否加密
+ *
+ * @param isEn 是否加密
* @param keyType 密钥类型 0: ZEK,1: TEK
- * @param key 密钥
- * @param inType 输入消息类型 0:二进制 1:扩展十六进制
+ * @param key 密钥
+ * @param inType 输入消息类型 0:二进制 1:扩展十六进制
* @param outType 输出消息类型 0:二进制 1:扩展十六进制
- * @param msg 消息数据
- * @param iv iv
- * @param block 消息块号
+ * @param msg 消息数据
+ * @param iv iv
+ * @param block 消息块号
* @return
*/
// @Override
@@ -5148,11 +5385,12 @@ public class SydApi4j implements SydApi {
* 使用SM4算法进行加密,其中加密模式为CBC,
* Ⅳ使用缺省值0X 00000000000000000000000000000000,
* 补位模式为 PKCS5 PADDING 。
+ *
* @param keyType 密钥类型 0: ZEK,1: TEK
- * @param key 密钥
- * @param inType 输入消息类型 0:二进制 1:扩展十六进制
+ * @param key 密钥
+ * @param inType 输入消息类型 0:二进制 1:扩展十六进制
* @param outType 输出消息类型 0:二进制 1:扩展十六进制
- * @param msg 消息数据
+ * @param msg 消息数据
* @return 输出的报文密文
*/
// 测试通过
@@ -5186,11 +5424,12 @@ public class SydApi4j implements SydApi {
* 使用SM4算法进行解密,其中加密模式为CBC,
* Ⅳ使用缺省值0X 00000000000000000000000000000000,
* 补位模式为 PKCS5 PADDING 。
- * @param keyType 密钥类型 0: ZEK,1: TEK
- * @param key 密钥
- * @param inType 输入消息类型 0:二进制 1:扩展十六进制
- * @param outType 输出消息类型 0:二进制 1:扩展十六进制
- * @param inFilePath 加密后的密文数据将要保存的文件路径
+ *
+ * @param keyType 密钥类型 0: ZEK,1: TEK
+ * @param key 密钥
+ * @param inType 输入消息类型 0:二进制 1:扩展十六进制
+ * @param outType 输出消息类型 0:二进制 1:扩展十六进制
+ * @param inFilePath 加密后的密文数据将要保存的文件路径
* @param outFilePath 解密后的数据文件所在的路径
* @return 解密是否成功。false为失败,true为成功
*/
@@ -5224,21 +5463,21 @@ public class SydApi4j implements SydApi {
File in = new File(inFilePath);
- if ( !in.exists() ){
+ if (!in.exists()) {
throw new SydApiException("要解密的文件不存在", -27);
}
long length = in.length();
int l = new Long(length).intValue();
- int n = l / ( 2 * 1024);
- println("n 个 2k:"+n);
+ int n = l / (2 * 1024);
+ println("n 个 2k:" + n);
- if (l % ( 2 * 1024) != 0) {
+ if (l % (2 * 1024) != 0) {
n++;
}
File out = new File(outFilePath);
- if ( out.exists() ){
+ if (out.exists()) {
out.delete();
}
try {
@@ -5255,22 +5494,22 @@ public class SydApi4j implements SydApi {
byte[] buff = new byte[2 * 1024];
byte[] buff1 = new byte[2 * 1024 + 16];
- for (int i = 0; i < n-1; i++) {
- int len = fis.read( buff );
+ for (int i = 0; i < n - 1; i++) {
+ int len = fis.read(buff);
//先判断是否是最后一块/唯一块,是->calc,
//首块和中间块才->update
- if ( len == buff.length){
- println("len长度_update:"+len);
- byte[] en = sym.update( buff );
- println("en长度:"+en.length);
- fos.write( en );
+ if (len == buff.length) {
+ println("len长度_update:" + len);
+ byte[] en = sym.update(buff);
+ println("en长度:" + en.length);
+ fos.write(en);
}
}
- int len = fis.read( buff1 );
+ int len = fis.read(buff1);
//先判断是否是最后一块/唯一块,是->calc,
//首块和中间块才->update
- if ( len <= buff1.length && len>-1) {
+ if (len <= buff1.length && len > -1) {
println("len长度_calc:" + len);
byte[] en = sym.calc(buff1, len);
println("en长度:" + en.length);
@@ -5303,11 +5542,12 @@ public class SydApi4j implements SydApi {
* 使用SM4算法进行解密,其中加密模式为CBC,
* Ⅳ使用缺省值0X 00000000000000000000000000000000,
* 补位模式为 PKCS5 PADDING 。
+ *
* @param keyType 密钥类型 0: ZEK,1: TEK
- * @param key 密钥
- * @param inType 输入消息类型 0:二进制 1:扩展十六进制
+ * @param key 密钥
+ * @param inType 输入消息类型 0:二进制 1:扩展十六进制
* @param outType 输出消息类型 0:二进制 1:扩展十六进制
- * @param msg 加密后的消息数据
+ * @param msg 加密后的消息数据
* @return 输出的报文明文
*/
// 测试通过
@@ -5783,7 +6023,7 @@ public class SydApi4j implements SydApi {
/**
* 8.1生成一个MAC(=)
*
- * @param TAK tak类型的密钥
+ * @param TAK tak类型的密钥
* @param infoData MAC数据,数据长度应该为8的整数倍,如果不是8的整数倍,系统默认在数据后面填充0x00组成8的整数倍。
* @param IV IV
* @return 所计算出的MAC hex 格式
@@ -6011,12 +6251,13 @@ public class SydApi4j implements SydApi {
/**
* 生成一个MAC
- * @param alg 算法,0=DES 1=3DES 2=SM4 3=AES 4=IDEA 5=SM1 6=3DES-X9.19
- * @param keyType 密钥类型,0-TAK 1-ZAK
- * @param AK 密钥
+ *
+ * @param alg 算法,0=DES 1=3DES 2=SM4 3=AES 4=IDEA 5=SM1 6=3DES-X9.19
+ * @param keyType 密钥类型,0-TAK 1-ZAK
+ * @param AK 密钥
* @param fullMode 填充类型,0-弱填充 1 强填充
* @param infoData MAC数据
- * @param macLen MAC数据长度,1=4Byte 2=8Byte 3=16Byte(仅在SM4/AES 下有效)
+ * @param macLen MAC数据长度,1=4Byte 2=8Byte 3=16Byte(仅在SM4/AES 下有效)
* @return mac 值 hex 格式
*/
// 测试通过
@@ -6979,7 +7220,7 @@ public class SydApi4j implements SydApi {
packet.put("data", data);
PacketSN sn = PacketSN.gen();
packet.put("header", sn.getSn().array());
- if (num != null && !"".equals(num)){
+ if (num != null && !"".equals(num)) {
data.put("num", num);
}
@@ -7927,22 +8168,23 @@ public class SydApi4j implements SydApi {
/**
* 自动 4k 分包
+ *
* @param keyType
* @param mode
* @param key
* @param msg
* @return MAC 值
*/
- public String genMAB(int mode, int keyType, String key, byte[] msg){
+ public String genMAB(int mode, int keyType, String key, byte[] msg) {
final int blockSize = 4 * 1024;
- if ( null == msg || msg.length == 0 ) {
+ if (null == msg || msg.length == 0) {
throw new SydApiException("输入数据为空", 21);
}
- if( msg.length <= blockSize ) {
+ if (msg.length <= blockSize) {
// 唯一包
- RetWrap retWrap = this.genMAB(0, keyType, 2, key, null, msg );
- return new String( (byte[]) retWrap.get("MAB") );
+ RetWrap retWrap = this.genMAB(0, keyType, 2, key, null, msg);
+ return new String((byte[]) retWrap.get("MAB"));
}
int loop = 0;
@@ -7961,31 +8203,31 @@ public class SydApi4j implements SydApi {
// 首包
// 必然有
- data = new byte[ blockSize ];
- System.arraycopy( msg, 0, data, 0 , data.length );
- RetWrap retWrap = this.genMAB(1, keyType, 2, key, null, data );
+ data = new byte[blockSize];
+ System.arraycopy(msg, 0, data, 0, data.length);
+ RetWrap retWrap = this.genMAB(1, keyType, 2, key, null, data);
byte[] iv = (byte[]) retWrap.get("MAB");
// 中间包
- for ( int i = 0 ; i < (loop - 2); i++ ) {
- data = new byte[ blockSize ];
- System.arraycopy( msg, (i + 1) * blockSize , data, 0 , data.length );
- retWrap = this.genMAB(2, keyType, 2, key, iv, data );
+ for (int i = 0; i < (loop - 2); i++) {
+ data = new byte[blockSize];
+ System.arraycopy(msg, (i + 1) * blockSize, data, 0, data.length);
+ retWrap = this.genMAB(2, keyType, 2, key, iv, data);
iv = (byte[]) retWrap.get("MAB");
}
// 尾包
// 必然有
- if( 0 == tailLen ) {
+ if (0 == tailLen) {
// 恰好是分包整倍数
tailLen = blockSize;
}
- data = new byte[ tailLen ];
- System.arraycopy( msg, (loop - 1) * blockSize , data, 0 , data.length );
- retWrap = this.genMAB(3, keyType, 2, key, iv , data);
- return new String( (byte[]) retWrap.get("MAB") );
+ data = new byte[tailLen];
+ System.arraycopy(msg, (loop - 1) * blockSize, data, 0, data.length);
+ retWrap = this.genMAB(3, keyType, 2, key, iv, data);
+ return new String((byte[]) retWrap.get("MAB"));
}
/**
@@ -9591,9 +9833,6 @@ public class SydApi4j implements SydApi {
}
-
-
-
/**
* 17.9 角色认证(+) -> -> : code = 2 ( 0x2 ) msg = 签名验证错误
*
@@ -9856,11 +10095,11 @@ public class SydApi4j implements SydApi {
/**
* 查询设备证书信息
- * @return
- * equipType: 设备型号
- * equipNo: 设备序号
- * equipPk: 设备密钥公钥
- * authSign: 授权签名
+ *
+ * @return equipType: 设备型号
+ * equipNo: 设备序号
+ * equipPk: 设备密钥公钥
+ * authSign: 授权签名
*/
// 测试通过
@Override
@@ -10022,8 +10261,7 @@ public class SydApi4j implements SydApi {
*
* @param orgData 待签名数据
* @param sCertDN 证书DN
- * @return
- * 符合PKCS7标准的签名结果
+ * @return 符合PKCS7标准的签名结果
*/
@Override
public String attachedSign(byte[] orgData, String sCertDN) {
@@ -10109,7 +10347,7 @@ public class SydApi4j implements SydApi {
byte[] be = error.getBytes();
if ((0 != (be[0] ^ be[1]))) {
SydApiException e = new SydApiException(error.getInfo(), error.autoInt());
- println("验签失败=" + e.toString() );
+ println("验签失败=" + e.toString());
return false;
}
@@ -10131,8 +10369,7 @@ public class SydApi4j implements SydApi {
* 对指定的原始数据核验其带公钥证书签名。如签名有效(含证书无效)且需返回签名者公钥证书信息时,同时返回签名者公钥证书信息。
*
* @param sign 已签名数据
- * @return
- * 返回CERT_INFO结构的证书数据
+ * @return 返回CERT_INFO结构的证书数据
*/
public X509 attachedVerifyAndGetX509(String sign) {
RetWrap retWrap = attachedVerifyAndGetAll(sign);
@@ -11218,13 +11455,13 @@ public class SydApi4j implements SydApi {
int algorithmKey = MyUtil.transAlg(algFlag);
bb.put(String.format("%02d", algorithmKey).getBytes());
- if (6==algorithmKey || 8==algorithmKey || 2==algorithmKey || 4==algorithmKey || 10==algorithmKey) {
+ if (6 == algorithmKey || 8 == algorithmKey || 2 == algorithmKey || 4 == algorithmKey || 10 == algorithmKey) {
// IV 数据域
bb.put(iv);
}
// 保护密钥分散级数
- bb.put(( String.valueOf( protectedKeyDivNum ) ).getBytes());
+ bb.put((String.valueOf(protectedKeyDivNum)).getBytes());
if (protectedKeyDivNum != 0) {
// 分散因子
@@ -11247,11 +11484,11 @@ public class SydApi4j implements SydApi {
bb.put(String.format("%02d", exportKeyNum).getBytes());
//导出的密钥结构体
- byte[] b = new byte[ 144 * exportKeyNum ];
- int destPos=0;
- for(Struct struct:structList){
- System.arraycopy(struct.getByte(),0,b,destPos,struct.getByte().length);
- destPos+=struct.getByte().length;
+ byte[] b = new byte[144 * exportKeyNum];
+ int destPos = 0;
+ for (Struct struct : structList) {
+ System.arraycopy(struct.getByte(), 0, b, destPos, struct.getByte().length);
+ destPos += struct.getByte().length;
}
bb.put(b);
diff --git a/src/test/java/com/sunyard/sydapi/test/TestHT.java b/src/test/java/com/sunyard/sydapi/test/TestHT.java
index b2ef83b..34ccec4 100644
--- a/src/test/java/com/sunyard/sydapi/test/TestHT.java
+++ b/src/test/java/com/sunyard/sydapi/test/TestHT.java
@@ -4,15 +4,13 @@ import com.sunyard.RetWrap;
import com.sunyard.SydApi;
import com.sunyard.cert.X509;
import com.sunyard.proto.Util;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import racal.sunyard.main.SydApi4j;
import java.io.UnsupportedEncodingException;
-import java.util.Base64;
-
-import static com.sunyard.sydapi.util.PrintUtil.printRetWrap;
/**
* 衡泰例子
@@ -25,7 +23,7 @@ public class TestHT {
public void before() {
// 通过设置debug的属性开启debug,如果不设置则默认不打开
System.setProperty("com.sunyard.sydapi4j.debug", "true");
- api = (SydApi4j) new SydApi4j().connect("172.16.18.59", 8889, null, 1000);
+ api = (SydApi4j) new SydApi4j().connect("192.168.0.200", 8889, null, 1000);
// api = (SydApi4j) new SydApi4j().connect("192.168.0.66", 8889, null, 1000);
}
@@ -39,6 +37,46 @@ public class TestHT {
}
+ @Test
+ public void testDecryptDE5() throws UnsupportedEncodingException {
+ String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
+ String oData = "00001111222233";
+
+ RetWrap retWrap = api.generateDEByDn(dn, oData);
+ String cipherKey = (String) retWrap.get(SydApi.RET_CIPHER_KEY);
+ System.out.println("数字信封: " + cipherKey);
+
+ RetWrap retWrap1 = api.decryptDEByDN(dn, cipherKey);
+ System.out.println("原数据: " + retWrap1.get("oData"));
+ }
+
+ @Test
+ public void testDecryptDE5Soft1() throws UnsupportedEncodingException {
+ String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
+ String oData = "00001111222233";
+
+ RetWrap retWrap = api.generateDEByDnSoft(dn, oData);
+ String cipherKey = (String) retWrap.get(SydApi.RET_CIPHER_KEY);
+ System.out.println("数字信封: " + cipherKey);
+
+ RetWrap retWrap1 = api.decryptDEByDN(dn, cipherKey);
+ System.out.println("原数据: " + retWrap1.get("oData"));
+ }
+
+ @Test
+ public void testDecryptDE5Soft2() throws UnsupportedEncodingException {
+ String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
+ String oData = "00001111222233";
+
+ RetWrap retWrap = api.generateDEByDn(dn, oData);
+ String cipherKey = (String) retWrap.get(SydApi.RET_CIPHER_KEY);
+ System.out.println("数字信封: " + cipherKey);
+
+ RetWrap retWrap1 = api.decryptDEByDNSoft(dn, cipherKey);
+ System.out.println("原数据: " + retWrap1.get("oData"));
+ }
+
+
//
// 测试通过
// 73
@@ -121,19 +159,19 @@ public class TestHT {
}
}
+
+
+
@Test
- public void testDecryptDE5() throws UnsupportedEncodingException {
+ public void getCert(){
String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
- String oData = "00001111222233";
-
- RetWrap retWrap = api.generateDEByDn(dn, oData);
- String cipherKey = (String) retWrap.get(SydApi.RET_CIPHER_KEY);
- System.out.println("数字信封: " + cipherKey);
-
- RetWrap retWrap1 = api.decryptDEByDN(dn, cipherKey);
- System.out.println("原数据: " + retWrap1.get("oData"));
+ String cert = api.GetX509CertFileBySN("1111111111111151", SydApi.FOR_ENCRYPT );
+ System.out.println( cert );
}
+
+
+
/**
* 流程演示
*/
diff --git a/src/test/java/com/sunyard/sydapi/util/SydCmsUtilTest.java b/src/test/java/com/sunyard/sydapi/util/SydCmsUtilTest.java
new file mode 100644
index 0000000..c249d4f
--- /dev/null
+++ b/src/test/java/com/sunyard/sydapi/util/SydCmsUtilTest.java
@@ -0,0 +1,83 @@
+package com.sunyard.sydapi.util;
+
+import com.sunyard.RetWrap;
+import com.sunyard.SydApi;
+import com.sunyard.proto.Util;
+import org.bouncycastle.asn1.cms.ContentInfo;
+import org.bouncycastle.cms.SydCmsUtil;
+
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.ASN1Set;
+import org.bouncycastle.asn1.ASN1TaggedObject;
+import org.bouncycastle.asn1.DEROctetString;
+import org.bouncycastle.asn1.cms.ContentInfo;
+import org.bouncycastle.cms.SydCmsUtil;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
+import org.junit.Test;
+import racal.sunyard.main.SydApi4j;
+
+
+public class SydCmsUtilTest {
+
+ @Test
+ public void test(){
+ SydApi4j api = (SydApi4j) new SydApi4j().connect("192.168.0.200", 8889, null, 1000);
+
+ try {
+ String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
+ String oData = "00001111222233";
+
+ RetWrap retWrap = api.generateDEByDnSoft(dn, oData);
+ String cipherKey = (String) retWrap.get(SydApi.RET_CIPHER_KEY);
+ System.out.println("数字信封: " + cipherKey);
+
+ RetWrap retWrap1 = api.decryptDEByDN(dn, cipherKey);
+ System.out.println("原数据: " + retWrap1.get("oData"));
+ }catch ( Exception e ) {
+ e.printStackTrace();
+ } finally {
+ if ( null != api ) {
+ api.disconnect();
+ }
+ }
+ }
+
+
+ public static void main(String[] args) {
+ System.setProperty("com.sunyard.sydapi4j.debug", "true");
+
+
+ String tmpl = "3082014D06092A864886F70D010703A082013E3082013A0201003181F73081F40201003065305C310B300906035504061302434E3130302E060355040A0C274368696E612046696E616E6369616C2043657274696669636174696F6E20417574686F72697479311B301906035504030C1243464341205445535420534D32204F43413102051004282452300B06092A811CCF5501822D03047B307902203C3AF535307DA548DA02C0AD171D2BC24D22472B42E5E175FCAF2C5CD30B5443022100ED53E7594F35FFACEB57F05898123F78E5B2D045CC47D894CD2E7BD34D66DA1D042014BD71F8CDA9729093A7CC391E2009C5D5F007586C2EBFB55BC175A6E8BDA33E04104AB82510BFDDD4FEE79C3F107D6F7F94303B060A2A811CCF550601040201301B06072A811CCF55016804100000000000000000000000000000000080109FD3D4338DB19E672CC162AF5B9B03E9";
+
+ System.out.println( SydCmsUtil.class.getClassLoader() );
+
+ ContentInfo info = SydCmsUtil.getContentInfo(Util.hexString2Bytes( tmpl ) );
+
+ System.out.println( info );
+
+ info = SydApi4j.genCMSEnvelopedData(new byte[0], new byte[0]);
+
+ SydApi4j api = (SydApi4j) new SydApi4j().connect("192.168.0.200", 8889, null, 1000);
+
+ try {
+ String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
+ String oData = "00001111222233";
+
+ RetWrap retWrap = api.generateDEByDnSoft(dn, oData);
+ String cipherKey = (String) retWrap.get(SydApi.RET_CIPHER_KEY);
+ System.out.println("数字信封: " + cipherKey);
+
+ RetWrap retWrap1 = api.decryptDEByDN(dn, cipherKey);
+ System.out.println("原数据: " + retWrap1.get("oData"));
+ }catch ( Exception e ) {
+ e.printStackTrace();
+ } finally {
+ if ( null != api ) {
+ api.disconnect();
+ }
+ }
+
+
+ }
+}