Skip to content

Commit bdf6e35

Browse files
author
Helperhaps
authored
Merge pull request #136 from boxingyewei/master
添加国密加密
2 parents 8d9537a + a5efb27 commit bdf6e35

File tree

10 files changed

+283
-55
lines changed

10 files changed

+283
-55
lines changed

example/main/java/cn/jpush/api/examples/PushExample.java

Lines changed: 61 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,34 @@
1-
package cn.jpush.api.examples;
2-
3-
import java.net.URI;
4-
import java.net.URISyntaxException;
5-
import java.util.Collection;
6-
import java.util.HashMap;
7-
import java.util.LinkedList;
8-
import java.util.Map;
1+
package main.java.cn.jpush.api.examples;
92

3+
import cn.jiguang.common.ClientConfig;
104
import cn.jiguang.common.ServiceHelper;
115
import cn.jiguang.common.connection.NativeHttpClient;
126
import cn.jiguang.common.connection.NettyHttpClient;
7+
import cn.jiguang.common.resp.APIConnectionException;
8+
import cn.jiguang.common.resp.APIRequestException;
139
import cn.jiguang.common.resp.ResponseWrapper;
10+
import cn.jpush.api.JPushClient;
1411
import cn.jpush.api.push.CIDResult;
1512
import cn.jpush.api.push.GroupPushClient;
13+
import cn.jpush.api.push.PushResult;
14+
import cn.jpush.api.push.model.*;
15+
import cn.jpush.api.push.model.audience.Audience;
16+
import cn.jpush.api.push.model.audience.AudienceTarget;
1617
import cn.jpush.api.push.model.notification.*;
17-
import com.google.gson.*;
18+
import com.google.gson.Gson;
19+
import com.google.gson.GsonBuilder;
20+
import com.google.gson.JsonObject;
21+
import com.google.gson.JsonPrimitive;
1822
import io.netty.handler.codec.http.HttpMethod;
1923
import org.slf4j.Logger;
2024
import org.slf4j.LoggerFactory;
2125

22-
import cn.jiguang.common.ClientConfig;
23-
import cn.jiguang.common.resp.APIConnectionException;
24-
import cn.jiguang.common.resp.APIRequestException;
25-
import cn.jpush.api.JPushClient;
26-
import cn.jpush.api.push.PushResult;
27-
import cn.jpush.api.push.model.Message;
28-
import cn.jpush.api.push.model.Options;
29-
import cn.jpush.api.push.model.Platform;
30-
import cn.jpush.api.push.model.PushPayload;
31-
import cn.jpush.api.push.model.SMS;
32-
import cn.jpush.api.push.model.audience.Audience;
33-
import cn.jpush.api.push.model.audience.AudienceTarget;
26+
import java.net.URI;
27+
import java.net.URISyntaxException;
28+
import java.util.Collection;
29+
import java.util.HashMap;
30+
import java.util.LinkedList;
31+
import java.util.Map;
3432

3533
public class PushExample {
3634
protected static final Logger LOG = LoggerFactory.getLogger(PushExample.class);
@@ -52,10 +50,10 @@ public class PushExample {
5250
public static void main(String[] args) {
5351
// testSendPushWithCustomConfig();
5452
// testSendIosAlert();
55-
testSendPush();
53+
// testSendPush();
5654
// testGetCidList();
5755
// testSendPushes();
58-
// testSendPush_fromJSON();
56+
testSendPush_fromJSON();
5957
// testSendPushWithCallback();
6058
// testSendPushWithCid();
6159
}
@@ -88,6 +86,42 @@ public static void testSendPush() {
8886
// Call setHttpClient to set httpClient,
8987
// If you don't invoke this method, default httpClient will use NativeHttpClient.
9088

89+
// ApacheHttpClient httpClient = new ApacheHttpClient(authCode, null, clientConfig);
90+
// NettyHttpClient httpClient =new NettyHttpClient(authCode, null, clientConfig);
91+
// jpushClient.getPushClient().setHttpClient(httpClient);
92+
final PushPayload payload = buildPushObject_android_and_ios();
93+
// // For push, all you need do is to build PushPayload object.
94+
// PushPayload payload = buildPushObject_all_alias_alert();
95+
try {
96+
PushResult result = jpushClient.sendPush(payload);
97+
LOG.info("Got result - " + result);
98+
System.out.println(result);
99+
// 如果使用 NettyHttpClient,需要手动调用 close 方法退出进程
100+
// If uses NettyHttpClient, call close when finished sending request, otherwise process will not exit.
101+
// jpushClient.close();
102+
} catch (APIConnectionException e) {
103+
LOG.error("Connection error. Should retry later. ", e);
104+
LOG.error("Sendno: " + payload.getSendno());
105+
106+
} catch (APIRequestException e) {
107+
LOG.error("Error response from JPush server. Should review and fix it. ", e);
108+
LOG.info("HTTP Status: " + e.getStatus());
109+
LOG.info("Error Code: " + e.getErrorCode());
110+
LOG.info("Error Message: " + e.getErrorMessage());
111+
LOG.info("Msg ID: " + e.getMsgId());
112+
LOG.error("Sendno: " + payload.getSendno());
113+
}
114+
}
115+
116+
public static void testSendPushWithEncrypt() {
117+
ClientConfig clientConfig = ClientConfig.getInstance();
118+
clientConfig.setEncryptType(EncryptKeys.ENCRYPT_SMS2_TYPE);
119+
final JPushClient jpushClient = new JPushClient(MASTER_SECRET, APP_KEY, null, clientConfig);
120+
// String authCode = ServiceHelper.getBasicAuthorization(APP_KEY, MASTER_SECRET);
121+
// Here you can use NativeHttpClient or NettyHttpClient or ApacheHttpClient.
122+
// Call setHttpClient to set httpClient,
123+
// If you don't invoke this method, default httpClient will use NativeHttpClient.
124+
91125
// ApacheHttpClient httpClient = new ApacheHttpClient(authCode, null, clientConfig);
92126
// NettyHttpClient httpClient =new NettyHttpClient(authCode, null, clientConfig);
93127
// jpushClient.getPushClient().setHttpClient(httpClient);
@@ -123,23 +157,23 @@ public static void testSendPush_fromJSON() {
123157
.registerTypeAdapter(PlatformNotification.class, new InterfaceAdapter<PlatformNotification>())
124158
.create();
125159
// Since the type of DeviceType is enum, thus the value should be uppercase, same with the AudienceType.
126-
String payloadString = "{\"platform\":{\"all\":false,\"deviceTypes\":[\"IOS\"]},\"audience\":{\"all\":false,\"targets\":[{\"audienceType\":\"TAG_AND\",\"values\":[\"tag1\",\"tag_all\"]}]},\"notification\":{\"notifications\":[{\"soundDisabled\":false,\"badgeDisabled\":false,\"sound\":\"happy\",\"badge\":\"5\",\"contentAvailable\":false,\"alert\":\"Test from API Example - alert\",\"extras\":{\"from\":\"JPush\"},\"type\":\"cn.jpush.api.push.model.notification.IosNotification\"}]},\"message\":{\"msgContent\":\"Test from API Example - msgContent\"},\"options\":{\"sendno\":1429488213,\"overrideMsgId\":0,\"timeToLive\":-1,\"apnsProduction\":true,\"bigPushDuration\":0}}";
160+
String payloadString = "{\"platform\":{\"all\":false,\"deviceTypes\":[\"IOS\"]},\"audience\":{\"all\":true,\"targets\":[{\"audienceType\":\"TAG_AND\",\"values\":[\"tag1\",\"tag_all\"]}]},\"notification\":{\"notifications\":[{\"soundDisabled\":false,\"badgeDisabled\":false,\"sound\":\"happy\",\"badge\":\"5\",\"contentAvailable\":false,\"alert\":\"Test from API Example - alert\",\"extras\":{\"from\":\"JPush\"},\"type\":\"cn.jpush.api.push.model.notification.IosNotification\"}]},\"message\":{\"msgContent\":\"Test from API Example - msgContent\"},\"options\":{\"sendno\":1429488213,\"overrideMsgId\":0,\"timeToLive\":-1,\"apnsProduction\":true,\"bigPushDuration\":0}}";
127161
PushPayload payload = gson.fromJson(payloadString, PushPayload.class);
128162
try {
129-
PushResult result = jpushClient.sendPush(payload);
163+
PushResult result = jpushClient.sendPush(payloadString);
130164
LOG.info("Got result - " + result);
131165

132166
} catch (APIConnectionException e) {
133167
LOG.error("Connection error. Should retry later. ", e);
134-
LOG.error("Sendno: " + payload.getSendno());
168+
// LOG.error("Sendno: " + payload.getSendno());
135169

136170
} catch (APIRequestException e) {
137171
LOG.error("Error response from JPush server. Should review and fix it. ", e);
138172
LOG.info("HTTP Status: " + e.getStatus());
139173
LOG.info("Error Code: " + e.getErrorCode());
140174
LOG.info("Error Message: " + e.getErrorMessage());
141175
LOG.info("Msg ID: " + e.getMsgId());
142-
LOG.error("Sendno: " + payload.getSendno());
176+
//LOG.error("Sendno: " + payload.getSendno());
143177
}
144178
}
145179

pom.xml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
<groupId>cn.jpush.api</groupId>
55
<artifactId>jpush-client</artifactId>
6-
<version>3.3.12-SNAPSHOT</version>
6+
<version>3.3.12</version>
77
<packaging>jar</packaging>
88
<url>https://github.com/jpush/jpush-api-java-client</url>
99
<name>JPush API Java Client</name>
@@ -42,7 +42,7 @@
4242
<dependency>
4343
<groupId>cn.jpush.api</groupId>
4444
<artifactId>jiguang-common</artifactId>
45-
<version>1.1.3</version>
45+
<version>1.1.6</version>
4646
</dependency>
4747
<dependency>
4848
<groupId>org.apache.httpcomponents</groupId>
@@ -84,7 +84,19 @@
8484
<scope>test</scope>
8585
</dependency>
8686

87-
<dependency>
87+
<dependency>
88+
<groupId>org.bouncycastle</groupId>
89+
<artifactId>bcprov-jdk15on</artifactId>
90+
<version>1.60</version>
91+
</dependency>
92+
<dependency>
93+
<groupId>org.bouncycastle</groupId>
94+
<artifactId>bcpkix-jdk15on</artifactId>
95+
<version>1.60</version>
96+
</dependency>
97+
98+
99+
<dependency>
88100
<groupId>junit</groupId>
89101
<artifactId>junit</artifactId>
90102
<version>4.11</version>

src/main/java/cn/jpush/api/push/GroupPushClient.java

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@
88
import cn.jiguang.common.resp.APIConnectionException;
99
import cn.jiguang.common.resp.APIRequestException;
1010
import cn.jiguang.common.resp.ResponseWrapper;
11+
import cn.jiguang.common.utils.Base64;
1112
import cn.jiguang.common.utils.Preconditions;
13+
import cn.jiguang.common.utils.sm2.SM2Util;
14+
import cn.jpush.api.push.model.EncryptKeys;
15+
import cn.jpush.api.push.model.EncryptPushPayload;
1216
import cn.jpush.api.push.model.PushPayload;
1317
import com.google.gson.Gson;
1418
import com.google.gson.reflect.TypeToken;
@@ -23,6 +27,7 @@ public class GroupPushClient {
2327
private IHttpClient _httpClient;
2428
private String _baseUrl;
2529
private String _groupPushPath;
30+
private String _encryptType;
2631
private Gson _gson = new Gson();
2732

2833
public GroupPushClient(String groupMasterSecret, String groupKey) {
@@ -33,16 +38,39 @@ public GroupPushClient(String groupMasterSecret, String groupKey, HttpProxy prox
3338
ServiceHelper.checkBasic(groupKey, groupMasterSecret);
3439
this._baseUrl = (String) conf.get(ClientConfig.PUSH_HOST_NAME);
3540
this._groupPushPath = (String) conf.get(ClientConfig.GROUP_PUSH_PATH);
41+
this._encryptType = (String) conf.get(ClientConfig.ENCRYPT_TYPE);
3642
String authCode = ServiceHelper.getBasicAuthorization("group-" + groupKey, groupMasterSecret);
3743
this._httpClient = new NativeHttpClient(authCode, proxy, conf);
3844
}
3945

4046
public Map<String, PushResult> sendGroupPush(PushPayload pushPayload) throws APIConnectionException, APIRequestException {
4147
Preconditions.checkArgument(! (null == pushPayload), "pushPayload should not be null");
42-
43-
ResponseWrapper response = _httpClient.sendPost(_baseUrl + _groupPushPath, pushPayload.toString());
48+
ResponseWrapper response = _httpClient.sendPost(_baseUrl + _groupPushPath, getEncryptData(pushPayload));
4449
return _gson.fromJson(response.responseContent,
4550
new TypeToken<Map<String, PushResult>>(){}.getType());
4651
}
4752

53+
/**
54+
* 获取加密的payload数据
55+
* @param pushPayload
56+
* @return
57+
*/
58+
private String getEncryptData(PushPayload pushPayload) {
59+
if (_encryptType.isEmpty()) {
60+
return pushPayload.toString();
61+
}
62+
if (EncryptKeys.ENCRYPT_SMS2_TYPE.equals(_encryptType)) {
63+
EncryptPushPayload encryptPushPayload = new EncryptPushPayload();
64+
try {
65+
encryptPushPayload.setPayload(String.valueOf(Base64.encode(SM2Util.encrypt(pushPayload.toString(), EncryptKeys.DEFAULT_SM2_ENCRYPT_KEY))));
66+
} catch (Exception e) {
67+
throw new RuntimeException("encrypt word exception", e);
68+
}
69+
encryptPushPayload.setAudience(pushPayload.getAudience());
70+
return encryptPushPayload.toString();
71+
}
72+
// 不支持的加密默认不加密
73+
return pushPayload.toString();
74+
}
75+
4876
}

src/main/java/cn/jpush/api/push/PushClient.java

Lines changed: 79 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
package cn.jpush.api.push;
22

3-
import cn.jiguang.common.connection.*;
4-
import com.google.gson.JsonParseException;
5-
import com.google.gson.JsonParser;
6-
73
import cn.jiguang.common.ClientConfig;
84
import cn.jiguang.common.ServiceHelper;
9-
import cn.jiguang.common.utils.Preconditions;
10-
import cn.jiguang.common.utils.StringUtils;
5+
import cn.jiguang.common.connection.*;
116
import cn.jiguang.common.resp.APIConnectionException;
127
import cn.jiguang.common.resp.APIRequestException;
138
import cn.jiguang.common.resp.BaseResult;
149
import cn.jiguang.common.resp.ResponseWrapper;
10+
import cn.jiguang.common.utils.Base64;
11+
import cn.jiguang.common.utils.Preconditions;
12+
import cn.jiguang.common.utils.StringUtils;
13+
import cn.jiguang.common.utils.sm2.SM2Util;
14+
import cn.jpush.api.push.model.EncryptKeys;
15+
import cn.jpush.api.push.model.EncryptPushPayload;
1516
import cn.jpush.api.push.model.PushPayload;
17+
import cn.jpush.api.push.model.audience.Audience;
18+
import com.google.gson.JsonElement;
19+
import com.google.gson.JsonObject;
20+
import com.google.gson.JsonParseException;
21+
import com.google.gson.JsonParser;
1622

1723
/**
1824
* Entrance for sending Push.
@@ -39,6 +45,9 @@ public class PushClient {
3945
// If not present, the default value is 86400(s) (one day)
4046
private long _timeToLive;
4147

48+
// encrypt type, the default value is empty
49+
private String _encryptType;
50+
4251
/**
4352
* Create a Push Client.
4453
*
@@ -96,6 +105,7 @@ public PushClient(String masterSecret, String appKey, HttpProxy proxy, ClientCon
96105

97106
this._apnsProduction = (Integer) conf.get(ClientConfig.APNS_PRODUCTION);
98107
this._timeToLive = (Long) conf.get(ClientConfig.TIME_TO_LIVE);
108+
this._encryptType = (String) conf.get(ClientConfig.ENCRYPT_TYPE);
99109

100110
String authCode = ServiceHelper.getBasicAuthorization(appKey, masterSecret);
101111
this._httpClient = new NativeHttpClient(authCode, proxy, conf);
@@ -157,7 +167,7 @@ public PushResult sendPush(PushPayload pushPayload) throws APIConnectionExceptio
157167
pushPayload.resetOptionsTimeToLive(_timeToLive);
158168
}
159169

160-
ResponseWrapper response = _httpClient.sendPost(_baseUrl + _pushPath, pushPayload.toString());
170+
ResponseWrapper response = _httpClient.sendPost(_baseUrl + _pushPath, getEncryptData(pushPayload));
161171

162172
return BaseResult.fromResponse(response, PushResult.class);
163173
}
@@ -175,7 +185,7 @@ public PushResult sendPushValidate(PushPayload pushPayload) throws APIConnection
175185
pushPayload.resetOptionsTimeToLive(_timeToLive);
176186
}
177187

178-
ResponseWrapper response = _httpClient.sendPost(_baseUrl + _pushValidatePath, pushPayload.toString());
188+
ResponseWrapper response = _httpClient.sendPost(_baseUrl + _pushValidatePath, getEncryptData(pushPayload));
179189

180190
return BaseResult.fromResponse(response, PushResult.class);
181191
}
@@ -189,7 +199,7 @@ public PushResult sendPush(String payloadString) throws APIConnectionException,
189199
Preconditions.checkArgument(false, "payloadString should be a valid JSON string.");
190200
}
191201

192-
ResponseWrapper response = _httpClient.sendPost(_baseUrl + _pushPath, payloadString);
202+
ResponseWrapper response = _httpClient.sendPost(_baseUrl + _pushPath, getEncryptData(payloadString));
193203

194204
return BaseResult.fromResponse(response, PushResult.class);
195205
}
@@ -203,7 +213,7 @@ public PushResult sendPushValidate(String payloadString) throws APIConnectionExc
203213
Preconditions.checkArgument(false, "payloadString should be a valid JSON string.");
204214
}
205215

206-
ResponseWrapper response = _httpClient.sendPost(_baseUrl + _pushValidatePath, payloadString);
216+
ResponseWrapper response = _httpClient.sendPost(_baseUrl + _pushValidatePath, getEncryptData(payloadString));
207217

208218
return BaseResult.fromResponse(response, PushResult.class);
209219
}
@@ -240,6 +250,65 @@ public void close() {
240250
((ApacheHttpClient) _httpClient).close();
241251
}
242252
}
253+
254+
/**
255+
* 获取加密的payload数据
256+
* @param payloadData
257+
* @return
258+
*/
259+
private String getEncryptData(String payloadData) {
260+
JsonElement payloadElement = _jsonParser.parse(payloadData);
261+
JsonObject jsonObject = payloadElement.getAsJsonObject();
262+
Audience audience = Audience.fromJsonElement(jsonObject.get("audience"));
263+
return getEncryptData(payloadData, audience);
264+
}
265+
266+
/**
267+
* 获取加密的payload数据
268+
* @param pushPayload
269+
* @return
270+
*/
271+
private String getEncryptData(PushPayload pushPayload) {
272+
if (_encryptType.isEmpty()) {
273+
return pushPayload.toString();
274+
}
275+
if (EncryptKeys.ENCRYPT_SMS2_TYPE.equals(_encryptType)) {
276+
EncryptPushPayload encryptPushPayload = new EncryptPushPayload();
277+
try {
278+
encryptPushPayload.setPayload(String.valueOf(Base64.encode(SM2Util.encrypt(pushPayload.toString(), EncryptKeys.DEFAULT_SM2_ENCRYPT_KEY))));
279+
} catch (Exception e) {
280+
throw new RuntimeException("encrypt word exception", e);
281+
}
282+
encryptPushPayload.setAudience(pushPayload.getAudience());
283+
return encryptPushPayload.toString();
284+
}
285+
// 不支持的加密默认不加密
286+
return pushPayload.toString();
287+
}
288+
289+
/**
290+
* 获取加密的payload数据
291+
* @param pushPayload
292+
* @return
293+
*/
294+
private String getEncryptData(String pushPayload, Audience audience) {
295+
if (_encryptType.isEmpty()) {
296+
return pushPayload;
297+
}
298+
if (EncryptKeys.ENCRYPT_SMS2_TYPE.equals(_encryptType)) {
299+
EncryptPushPayload encryptPushPayload = new EncryptPushPayload();
300+
try {
301+
encryptPushPayload.setPayload(String.valueOf(Base64.encode(SM2Util.encrypt(pushPayload, EncryptKeys.DEFAULT_SM2_ENCRYPT_KEY))));
302+
} catch (Exception e) {
303+
throw new RuntimeException("encrypt word exception", e);
304+
}
305+
encryptPushPayload.setAudience(audience);
306+
return encryptPushPayload.toString();
307+
}
308+
// 不支持的加密默认不加密
309+
return pushPayload;
310+
}
311+
243312
}
244313

245314

0 commit comments

Comments
 (0)