开发前必读
申请app_key及app_secret
[!NOTE]
测试环境联系君子签技术支持发放初始的 app_key和 app_secret。
正式环境需在君子签官网进行企业注册认证,认证通过后,联系君子签技术支持发放初始的 app_key和 app_secret。
电子签合规说明
[!NOTE]
友情提示:
1、应CA机构要求,需要收集签约方的身份证照资料(如身份证正反面,营业执照等),对接平台需留存签约方的身份证照资料,若不能按要求提供导致CA证书被吊销或者君子签被CA机构追责, 一切后果由接入平台承担。
2、接入平台应当向君子签合作的CA机构提供真实有效的身份信息,若提供虚构伪造、不合规的身份信息,CA机构将拒绝颁发数字证书,使用该身份信息签署的电子文件没有数字证书,签署的电子文件无效。
接口调用说明
[!NOTE]
1、接口为http请求的参数传参(即像form表单提交的方式传值)即可( 其中 ts、 sign、
app_key,nonce 为特殊必填参数(encry_method为选填,默认不填写时encry_method=sha256)。 其它参数根据不同的接口地址, 相应的追加参数请求)。
2、对于要上传文件的情况, 请使用form的文件上传方式传值
3、请求的接口地址为 $SERVICE_URL/业务地址4、为保障服务稳定性,君子签正式生产环境禁止进行性能压测和安全渗透测试。君子签沙箱环境进行性能压测和安全渗透测试时,需先向君子签技术顾问报备,获取许可后才能进行相关操作。否则君子签安全团队有权采取相关措施进行拦截。
接口TPS限制说明
[!NOTE]
为保障电子签约接口的稳定性,TPS默认值是10次/秒,若贵司有更高的并发需求,需要付费提高TPS。TPS购买可联系商务顾问。
接口请求地址
[!NOTE]
接口测试地址
SERVICE_URL="https://api.sandbox.junziqian.com"
接口生产地址
SERVICE_URL="https://api.junziqian.com"
公共必填参数
参数名 | 说明 | 是否必填(*是) | 请求方式 |
---|---|---|---|
ts | 时间戳,取当前时间的毫秒值 | * | query或post |
app_key | 君子签提供的app_key | * | query或post |
sign | 对请求生成的签名,生成方式参考后续详细说明 | * | query或post |
nonce | 32位随机数(只能是[0-9a-f]) | * | post |
encry_method | 签名方式:md5,sha256,sha1,sha3_256;默认sha256 | ? | query或post |
[!NOTE]
请求方式:QUERY即建议参数附在URL地址上请求;POST即建议参数在REQUEST.BODY中传输(如nonce参数建议使用post请求并把参数放入请求的body中而不是以url的方式传输)
签名方法
nonce说明
[!NOTE]
nonce是32位的随机数,推荐获取方式为:md5(当前时间)的方式
sign说明
[!NOTE]
sign是对请求参数签名,签名方法如下:
1.指定一种签名方式:encry_method=md5,sha256,sha1,sha3_256
2.计算nonce: md5(ts)
3.获取到app_key,app_secret,ts
- 按如下规则:sign = $encry_method("nonce"+nonce+"ts"+ts+"app_key"+app_key+"app_secret"+secret
) 即生成字符串的哈希值
sha3-256签名说明
[!NOTE]
sha3-256这里使用的是apache的DigestUtil.sha3_256Hex(需要指定加密服务提供商为BouncyCastleProvider)方法生成(PHP的SDK中暂不支持)
<!--使用sha3-256签名的最低commons-codec版本要求,并需要引用BouncyCastleProvider-->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.13</version>
</dependency>
<!--
以下是一个对”123456”字符串签名后的结果:
sha1Hex:7c4a8d09ca3762af61e59520943dc26494f8941b
sha256Hex:8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92
md5Hex:e10adc3949ba59abbe56e057f20f883e
sha3_256Hex:c888c9ce9e098d5864d3ded6ebcc140a12142263bace3a23a36f9905f12bd64a
-->
代码实现
/**请求地址*/
private String serviceUrl;
/**appkey*/
private String appkey;
/**secret*/
private String appSecret;
/**默认加密方式:不输入使用sha256,其它可选择项md5,sha1,sha3-256*/
private String encryMethod;
/**默认ts单位:1毫秒,2秒*/
private byte tsType=(byte)1;
/**app_key*/
private String appKey;
/**app_secret*/
private String appSecret;
/**
* 填充签名数据
* @param req
*/
private void fillSign(Map<String,Object> req){
/**默认加密方式:不输入使用sha256,其它可选择项md5,sha1,sha3-256*/
long ts=System.currentTimeMillis();
if(tsType==2){
ts=System.currentTimeMillis()/1000;
}
String sign;
String nonce= DigestUtils.md5Hex(System.currentTimeMillis()+"");
String signSrc="nonce"+nonce+"ts"+ts+"app_key"+appkey+"app_secret"+appSecret;
if(encryMethod==null||encryMethod.equalsIgnoreCase("sha256")){
sign=DigestUtils.sha256Hex(signSrc);
}else if(encryMethod.equalsIgnoreCase("sha1")){
sign=DigestUtils.sha1Hex(signSrc);
}else if(encryMethod.equalsIgnoreCase("md5")){
sign=DigestUtils.md5Hex(signSrc);
}else if(encryMethod.equalsIgnoreCase("sha3-256")){
sign=DigestUtils.sha3_256Hex(signSrc);//*此需要引入加密商BouncyCastleProvider才能使用
}else{
throw new ResultInfoException("HTTP_PARAM_ERROR",encryMethod+",必须为md5,sha1,sha256,sha3-256之一");
}
req.put("ts",ts);
req.put("app_key",appkey);
req.put("sign",sign);
req.put("nonce",nonce);//这只只是为了生成一个随机值
if(encryMethod!=null){
req.put("encry_method",encryMethod);//为''也不会传,在requestUtils中有判断
}
}
/**请求地址*/
private $serviceUrl;
/**appkey*/
private $appkey;
/**secret*/
private $appSecret;
/**默认加密方式:不输入使用sha256,其它可选择项md5,sha1,sha3-256*/
private $encryMethod;
/**默认ts单位:1毫秒,2秒*/
private $tsType;
/**
* 填充签名数据
* @param $req array
*/
public function fillSign($req){
/**默认加密方式:不输入使用sha256,其它可选择项md5,sha1,sha3-256*/
$ts=time();
if($this->tsType==1){
$ts=$ts*1000;
}
$sign=null;
$nonce= md5($ts."");
$signSrc="nonce".$nonce."ts".$ts."app_key".$this->appkey."app_secret".$this->appSecret;
if($this->encryMethod==null||$this->encryMethod=="sha256"){
$sign=ShaUtils::getSha256($signSrc);
}else if($this->encryMethod=="sha1"){
$sign=ShaUtils::getSha1($signSrc);
}else if($this->encryMethod=="md5"){
$sign=md5($signSrc);
}else{
throw new ResultInfoException($this->encryMethod.",必须为md5,sha1,sha256之一","PARAM_ERROR");
}
$req['ts']=$ts;
$req['app_key']=$this->appkey;
$req['sign']=$sign;
$req['nonce']=$nonce;//这只是为了生成一个随机值
if($this->encryMethod!=null){
$req['encry_method']=$this->encryMethod;//为''也不能传
}
return $req;
}
参数是否必须传入
[!NOTE]
?表示可能存在;*表示必须; +表示选择性必填(其它字段在某些值时必填)
字段类型说明
类型 | 说明 |
---|---|
bool | boolean变量:true;false |
string | 字符串 |
int | 整数类型 |
long | 长整数类型 |
float/double | 符点类型 |
JSONObject | json对象(请求时需转为字符串) |
JSONArray | json数组对象(请求时需转为字符串) |
file/files | 文件/多个文件 |
object | json对象 |
请求方式
[!NOTE]
指明参数在请求中摆放的位置,默认建议使用post
类型 | 说明 |
---|---|
query | 即附在url地址后面以?XXX=XXX的方式请求 |
path | 即附在url中以/XXX/XXX的方式请求 |
post | 即把参数放在http.body中请求 |
返回说明
[!NOTE]
返回response为application/json的数据,其字段说明如下
参数 | 类型 | 是否必返回 | 说明 |
---|---|---|---|
success | bool | * | 成功true;异常false |
msg | string | ? | 异常时,返回异常原因 |
data | object | ? | 成功有数据,各接口不同返回值不同 |
resultCode | int | * | 失败时返回 |