Merge branch 'zhaoyue-dev2' into 'master'
Zhaoyue dev2 See merge request !27
Showing
9 changed files
with
445 additions
and
8 deletions
@@ -2,8 +2,8 @@ git pull | @@ -2,8 +2,8 @@ git pull | ||
2 | git add --all src/main/java/* | 2 | git add --all src/main/java/* |
3 | git add push.sh | 3 | git add push.sh |
4 | git add pom.xml | 4 | git add pom.xml |
5 | -git commit -m "add qrcode related code" | ||
6 | -git push origin master | ||
7 | -#git push origin zhaoyue-dev | 5 | +git commit -m "add qr related code" |
6 | +#git push origin master | ||
7 | +git push origin zhaoyue-dev2 | ||
8 | git status | 8 | git status |
9 | git pull | 9 | git pull |
@@ -76,5 +76,7 @@ public interface Constants { | @@ -76,5 +76,7 @@ public interface Constants { | ||
76 | 76 | ||
77 | public static final double SMALL_DOUBLE = 0.001; | 77 | public static final double SMALL_DOUBLE = 0.001; |
78 | 78 | ||
79 | - public static final String WEB_LOGIN_URL = "http://testingurl/?qrcode="; | 79 | + public static final String WEB_LOGIN_URL = "http://testingurl/?url="; |
80 | + public static final String LOCAL_QRVERIFY_URL = "https://www.hanhezy.com:8090/qrcode/getUsrInfoWithQr?encryptQr="; | ||
81 | + | ||
80 | } | 82 | } |
@@ -33,7 +33,10 @@ public enum ResultStatus { | @@ -33,7 +33,10 @@ public enum ResultStatus { | ||
33 | 33 | ||
34 | DB_ERROR(-11160,"服务器错误,无法写入数据库/Server error, can not write into database"), | 34 | DB_ERROR(-11160,"服务器错误,无法写入数据库/Server error, can not write into database"), |
35 | 35 | ||
36 | - COMPANY_ERROR(-11170,"用户所属公司信息有误/Company infomation error"); | 36 | + COMPANY_ERROR(-11170,"用户所属公司信息有误/Company information error"), |
37 | + | ||
38 | + // 112开头的与QR Code有关 | ||
39 | + INVALID_QR_CODE(-11201,"无效QR码/Invalid QR code"); | ||
37 | 40 | ||
38 | 41 | ||
39 | 42 |
@@ -23,7 +23,10 @@ import com.xkl.repository.XklMemberRespository; | @@ -23,7 +23,10 @@ import com.xkl.repository.XklMemberRespository; | ||
23 | import com.xkl.security.AntiXSS; | 23 | import com.xkl.security.AntiXSS; |
24 | import com.xkl.service.ILoginService; | 24 | import com.xkl.service.ILoginService; |
25 | import com.xkl.service.IQRCodeService; | 25 | import com.xkl.service.IQRCodeService; |
26 | +import com.xkl.service.QRCodeServiceImpl; | ||
27 | +import com.xkl.tools.DESTools; | ||
26 | import com.xkl.tools.DatetimeTools; | 28 | import com.xkl.tools.DatetimeTools; |
29 | +import com.xkl.tools.HttpTools; | ||
27 | import org.springframework.beans.factory.annotation.Autowired; | 30 | import org.springframework.beans.factory.annotation.Autowired; |
28 | import org.springframework.http.HttpStatus; | 31 | import org.springframework.http.HttpStatus; |
29 | import org.springframework.http.ResponseEntity; | 32 | import org.springframework.http.ResponseEntity; |
@@ -34,6 +37,7 @@ import org.springframework.web.bind.annotation.RequestParam; | @@ -34,6 +37,7 @@ import org.springframework.web.bind.annotation.RequestParam; | ||
34 | import org.springframework.web.bind.annotation.RestController; | 37 | import org.springframework.web.bind.annotation.RestController; |
35 | 38 | ||
36 | import javax.servlet.http.HttpServletRequest; | 39 | import javax.servlet.http.HttpServletRequest; |
40 | +import java.net.URLEncoder; | ||
37 | import java.text.SimpleDateFormat; | 41 | import java.text.SimpleDateFormat; |
38 | import java.util.Date; | 42 | import java.util.Date; |
39 | 43 | ||
@@ -123,8 +127,13 @@ public class QRCodeController { | @@ -123,8 +127,13 @@ public class QRCodeController { | ||
123 | @AntiXSS | 127 | @AntiXSS |
124 | @RequestMapping(value = "/getUsrInfoWithQr", method = RequestMethod.GET) | 128 | @RequestMapping(value = "/getUsrInfoWithQr", method = RequestMethod.GET) |
125 | @ApiOperation(value = "使用qrcode查询个人信息") | 129 | @ApiOperation(value = "使用qrcode查询个人信息") |
130 | + // 接口返回的qrcode都是正常的qrcode,但是客户端使用的时候必须加密才能使用。 | ||
126 | public ResponseEntity<ResultModel> getUsrInfoWithQr(HttpServletRequest request, | 131 | public ResponseEntity<ResultModel> getUsrInfoWithQr(HttpServletRequest request, |
127 | - @RequestParam String qrcode, @RequestParam long t) { | 132 | + @RequestParam String encryptQr, @RequestParam long t) { |
133 | + String qrcode = qrCodeService.getDecryptHttpParaQr(encryptQr, t); | ||
134 | + if (qrcode == null) { | ||
135 | + return new ResponseEntity<>(ResultModel.error(ResultStatus.INVALID_QR_CODE), HttpStatus.OK); | ||
136 | + } | ||
128 | String account = qrCodeService.getAccountWithQRCode(qrcode); | 137 | String account = qrCodeService.getAccountWithQRCode(qrcode); |
129 | User user = userRepository.findByLoginAccountAndStatus(account, true); | 138 | User user = userRepository.findByLoginAccountAndStatus(account, true); |
130 | if (user == null) { | 139 | if (user == null) { |
@@ -144,6 +153,13 @@ public class QRCodeController { | @@ -144,6 +153,13 @@ public class QRCodeController { | ||
144 | } | 153 | } |
145 | 154 | ||
146 | private static String genWebloginUrl(String qrcode) { | 155 | private static String genWebloginUrl(String qrcode) { |
147 | - return Constants.WEB_LOGIN_URL + qrcode.trim(); | 156 | + String now = HttpTools.getNow(); |
157 | + try { | ||
158 | + String encryptQr = DESTools.encrypt(qrcode.trim() + now, QRCodeServiceImpl.getHttpParaQrKey()); | ||
159 | + String interUrl = Constants.LOCAL_QRVERIFY_URL + encryptQr + "&t=" + now; | ||
160 | + return Constants.WEB_LOGIN_URL + URLEncoder.encode(interUrl, "utf-8"); | ||
161 | + } catch (Exception e) { | ||
162 | + return null; | ||
163 | + } | ||
148 | } | 164 | } |
149 | } | 165 | } |
@@ -7,4 +7,6 @@ public interface IQRCodeService { | @@ -7,4 +7,6 @@ public interface IQRCodeService { | ||
7 | public String getQRCodeWithAccount(String account); | 7 | public String getQRCodeWithAccount(String account); |
8 | 8 | ||
9 | public String getAccountWithQRCode(String qrcode); | 9 | public String getAccountWithQRCode(String qrcode); |
10 | + | ||
11 | + public String getDecryptHttpParaQr(String encryptQr, long t); | ||
10 | } | 12 | } |
@@ -21,6 +21,7 @@ import java.util.concurrent.TimeUnit; | @@ -21,6 +21,7 @@ import java.util.concurrent.TimeUnit; | ||
21 | public class QRCodeServiceImpl implements IQRCodeService, Constants { | 21 | public class QRCodeServiceImpl implements IQRCodeService, Constants { |
22 | private static final String REDIS_ACC_QR_PREFIX = "acc_qr-"; | 22 | private static final String REDIS_ACC_QR_PREFIX = "acc_qr-"; |
23 | private static final String REDIS_QR_ACC_PREFIX = "qr_acc-"; | 23 | private static final String REDIS_QR_ACC_PREFIX = "qr_acc-"; |
24 | + private static final String HTTP_PARA_QR_KEY = "tnvkqybFHp69pinDZJ7UWuX7"; | ||
24 | 25 | ||
25 | private RedisTemplate<String, String> redis; | 26 | private RedisTemplate<String, String> redis; |
26 | 27 | ||
@@ -29,6 +30,23 @@ public class QRCodeServiceImpl implements IQRCodeService, Constants { | @@ -29,6 +30,23 @@ public class QRCodeServiceImpl implements IQRCodeService, Constants { | ||
29 | this.redis = redis; | 30 | this.redis = redis; |
30 | } | 31 | } |
31 | 32 | ||
33 | + | ||
34 | + @Override | ||
35 | + public String getDecryptHttpParaQr(String encryptQr, long t) { | ||
36 | + String qrcode = ""; | ||
37 | + try { | ||
38 | + String str = DESTools.decrypt(encryptQr, HTTP_PARA_QR_KEY); | ||
39 | + if (str.endsWith(Long.toString(t))) { | ||
40 | + return str.replace(Long.toString(t), ""); | ||
41 | + } else { | ||
42 | + return null; | ||
43 | + } | ||
44 | + } catch (Exception e) { | ||
45 | + e.printStackTrace(); | ||
46 | + return null; | ||
47 | + } | ||
48 | + } | ||
49 | + | ||
32 | @Override | 50 | @Override |
33 | public String getAccountWithQRCode(String qrcode) { | 51 | public String getAccountWithQRCode(String qrcode) { |
34 | String qrAcckey = genQrAccKey(qrcode); | 52 | String qrAcckey = genQrAccKey(qrcode); |
@@ -69,4 +87,7 @@ public class QRCodeServiceImpl implements IQRCodeService, Constants { | @@ -69,4 +87,7 @@ public class QRCodeServiceImpl implements IQRCodeService, Constants { | ||
69 | return REDIS_QR_ACC_PREFIX + account; | 87 | return REDIS_QR_ACC_PREFIX + account; |
70 | } | 88 | } |
71 | 89 | ||
90 | + public static String getHttpParaQrKey() { | ||
91 | + return HTTP_PARA_QR_KEY; | ||
92 | + } | ||
72 | } | 93 | } |
@@ -12,7 +12,7 @@ import java.util.Random; | @@ -12,7 +12,7 @@ import java.util.Random; | ||
12 | */ | 12 | */ |
13 | public class DESTools { | 13 | public class DESTools { |
14 | /** | 14 | /** |
15 | - * 加密、解密key. | 15 | + * 加密、解密key,用作生成二维码之用,无其他用途。 |
16 | */ | 16 | */ |
17 | private static final String PASSWORD_CRYPT_KEY = "HhiTuqm7lsMVHYD4Bkj2B5jSUh0IKPNk"; | 17 | private static final String PASSWORD_CRYPT_KEY = "HhiTuqm7lsMVHYD4Bkj2B5jSUh0IKPNk"; |
18 | 18 | ||
@@ -66,6 +66,20 @@ public class DESTools { | @@ -66,6 +66,20 @@ public class DESTools { | ||
66 | } | 66 | } |
67 | 67 | ||
68 | /** | 68 | /** |
69 | + * 对数据进行DES加密. | ||
70 | + * | ||
71 | + * @param data 待进行DES加密的数据 | ||
72 | + * @return 返回经过DES加密后的数据 | ||
73 | + * @throws Exception | ||
74 | + * @author <a href="mailto:xiexingxing1121@126.com" mce_href="mailto:xiexingxing1121@126.com">AmigoXie</a> | ||
75 | + * Creation date: 2007-7-31 - 下午12:06:24 | ||
76 | + */ | ||
77 | + public final static String decrypt(String data, String key) throws Exception { | ||
78 | + return new String(decrypt(hex2byte(data.getBytes()), | ||
79 | + key.getBytes())); | ||
80 | + } | ||
81 | + | ||
82 | + /** | ||
69 | * 对用DES加密过的数据进行解密. | 83 | * 对用DES加密过的数据进行解密. |
70 | * | 84 | * |
71 | * @param data DES加密数据 | 85 | * @param data DES加密数据 |
@@ -79,6 +93,22 @@ public class DESTools { | @@ -79,6 +93,22 @@ public class DESTools { | ||
79 | .getBytes())); | 93 | .getBytes())); |
80 | } | 94 | } |
81 | 95 | ||
96 | + | ||
97 | + /** | ||
98 | + * 对用DES加密过的数据进行解密. | ||
99 | + * | ||
100 | + * @param data DES加密数据 | ||
101 | + * @return 返回解密后的数据 | ||
102 | + * @throws Exception | ||
103 | + * @author <a href="mailto:xiexingxing1121@126.com" mce_href="mailto:xiexingxing1121@126.com">AmigoXie</a> | ||
104 | + * Creation date: 2007-7-31 - 下午12:07:54 | ||
105 | + */ | ||
106 | + public final static String encrypt(String data, String key) throws Exception { | ||
107 | + return byte2hex(encrypt(data.getBytes(), key | ||
108 | + .getBytes())); | ||
109 | + } | ||
110 | + | ||
111 | + | ||
82 | /** | 112 | /** |
83 | * 用指定的key对数据进行DES加密. | 113 | * 用指定的key对数据进行DES加密. |
84 | * | 114 | * |
src/main/java/com/xkl/tools/HttpTools.java
0 → 100644
1 | +package com.xkl.tools; | ||
2 | + | ||
3 | +import java.io.BufferedReader; | ||
4 | +import java.io.DataOutputStream; | ||
5 | +import java.io.IOException; | ||
6 | +import java.io.InputStreamReader; | ||
7 | +import java.net.HttpURLConnection; | ||
8 | +import java.net.URL; | ||
9 | +import java.net.URLEncoder; | ||
10 | +import java.util.*; | ||
11 | + | ||
12 | +/** | ||
13 | + * Created by win7 on 2016/12/25. | ||
14 | + */ | ||
15 | +public class HttpTools { | ||
16 | + | ||
17 | + /** | ||
18 | + * 获取当前时间,10位 | ||
19 | + * @return | ||
20 | + */ | ||
21 | + public static String getNow(){ | ||
22 | + Calendar c = Calendar.getInstance();//可以对每个时间域单独修改 | ||
23 | + return String.valueOf(c.getTimeInMillis()/1000); | ||
24 | + } | ||
25 | + | ||
26 | + | ||
27 | + /** | ||
28 | + * 发送http请求 | ||
29 | + * @param url 请求url | ||
30 | + * @param type 请求类型:GET,POST,DELETE | ||
31 | + * @param params 请求参数:map类型 | ||
32 | + * @return | ||
33 | + */ | ||
34 | + public static String requestByMapWithToken(String url, String type, Map<String, String> params, String authorization){ | ||
35 | + String reqbody = getRequestData(params,"UTF-8").toString(); | ||
36 | + String result = requestByString(url + "?" + reqbody,type,authorization,null); | ||
37 | + return result; | ||
38 | + } | ||
39 | + | ||
40 | + public static String requestByMap(String url, String type,Map<String, String> params){ | ||
41 | + return requestByMapWithToken(url,type,params,""); | ||
42 | + } | ||
43 | + | ||
44 | + /** | ||
45 | + * 发送http请求 | ||
46 | + * @param url 请求url | ||
47 | + * @param type 请求类型:GET,POST,DELETE | ||
48 | + * @param reqbody 请求参数:String类型 | ||
49 | + * @return | ||
50 | + */ | ||
51 | + public static String requestByString(String url, String type, String authorization,String reqbody){ | ||
52 | + HttpURLConnection con = null; | ||
53 | + String result = null; | ||
54 | + try { | ||
55 | + con = getHttpConnection( url , type, authorization); | ||
56 | + //you can add any request body here if you want to post | ||
57 | + if( reqbody != null){ | ||
58 | + DataOutputStream out = new DataOutputStream(con.getOutputStream()); | ||
59 | + out.writeBytes(reqbody); | ||
60 | + out.flush(); | ||
61 | + out.close(); | ||
62 | + } | ||
63 | + con.connect(); | ||
64 | + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); | ||
65 | + String temp = null; | ||
66 | + StringBuilder sb = new StringBuilder(); | ||
67 | + while((temp = in.readLine()) != null){ | ||
68 | + sb.append(temp).append(" "); | ||
69 | + } | ||
70 | + result = sb.toString(); | ||
71 | + in.close(); | ||
72 | + } catch (IOException e) { | ||
73 | + System.out.println(e); | ||
74 | + } | ||
75 | + return result; | ||
76 | + | ||
77 | + } | ||
78 | + | ||
79 | + private static HttpURLConnection getHttpConnection(String url, String type, String authorization){ | ||
80 | + URL uri = null; | ||
81 | + HttpURLConnection con = null; | ||
82 | + try{ | ||
83 | + uri = new URL(url); | ||
84 | + con = (HttpURLConnection) uri.openConnection(); | ||
85 | + con.setRequestMethod(type); //type: POST, PUT, DELETE, GET | ||
86 | + if(type.equals("POST")) | ||
87 | + con.setDoOutput(true); | ||
88 | + con.setConnectTimeout(60000); //60 secs | ||
89 | + con.setReadTimeout(60000); //60 secs | ||
90 | + con.setRequestProperty("Content-Type", "application/json;charset=UTF-8"); | ||
91 | + con.setRequestProperty("authorization",authorization); | ||
92 | + }catch(Exception e){ | ||
93 | + System.out.println( "connection i/o failed" ); | ||
94 | + } | ||
95 | + | ||
96 | + | ||
97 | + return con; | ||
98 | + } | ||
99 | + | ||
100 | + private static StringBuffer getRequestData(Map<String, String> params, String encode) { | ||
101 | + StringBuffer stringBuffer = new StringBuffer(); //存储封装好的请求体信息 | ||
102 | + try { | ||
103 | + for(Map.Entry<String, String> entry : params.entrySet()) { | ||
104 | + stringBuffer.append(entry.getKey()) | ||
105 | + .append("=") | ||
106 | + .append(URLEncoder.encode(entry.getValue(), encode)) | ||
107 | + .append("&"); | ||
108 | + } | ||
109 | + stringBuffer.deleteCharAt(stringBuffer.length() - 1); //删除最后的一个"&" | ||
110 | + } catch (Exception e) { | ||
111 | + e.printStackTrace(); | ||
112 | + } | ||
113 | + return stringBuffer; | ||
114 | + } | ||
115 | + | ||
116 | +} |
src/main/java/com/xkl/tools/RSATools.java
0 → 100644
1 | +package com.xkl.tools; | ||
2 | + | ||
3 | +/** | ||
4 | + * Created by zhaoyue on 2017/3/13. | ||
5 | + */ | ||
6 | + | ||
7 | +import java.math.BigInteger; | ||
8 | +import java.security.KeyFactory; | ||
9 | +import java.security.KeyPair; | ||
10 | +import java.security.KeyPairGenerator; | ||
11 | +import java.security.NoSuchAlgorithmException; | ||
12 | +import java.security.interfaces.RSAPrivateKey; | ||
13 | +import java.security.interfaces.RSAPublicKey; | ||
14 | +import java.security.spec.RSAPrivateKeySpec; | ||
15 | +import java.security.spec.RSAPublicKeySpec; | ||
16 | +import java.util.HashMap; | ||
17 | + | ||
18 | +import javax.crypto.Cipher; | ||
19 | + | ||
20 | +public class RSATools { | ||
21 | + public static void main(String[] args) throws Exception { | ||
22 | + // TODO Auto-generated method stub | ||
23 | + HashMap<String, Object> map = RSATools.getKeys(); | ||
24 | + //生成公钥和私钥 | ||
25 | + RSAPublicKey publicKey = (RSAPublicKey) map.get("public"); | ||
26 | + RSAPrivateKey privateKey = (RSAPrivateKey) map.get("private"); | ||
27 | + | ||
28 | + //模 | ||
29 | + String modulus = publicKey.getModulus().toString(); | ||
30 | + //公钥指数 | ||
31 | + String public_exponent = publicKey.getPublicExponent().toString(); | ||
32 | + //私钥指数 | ||
33 | + String private_exponent = privateKey.getPrivateExponent().toString(); | ||
34 | + //明文 | ||
35 | + String ming = "123456789"; | ||
36 | + //使用模和指数生成公钥和私钥 | ||
37 | + RSAPublicKey pubKey = RSATools.getPublicKey(modulus, public_exponent); | ||
38 | + RSAPrivateKey priKey = RSATools.getPrivateKey(modulus, private_exponent); | ||
39 | + //加密后的密文 | ||
40 | + String mi = RSATools.encryptByPublicKey(ming, pubKey); | ||
41 | + System.err.println(mi); | ||
42 | + //解密后的明文 | ||
43 | + ming = RSATools.decryptByPrivateKey(mi, priKey); | ||
44 | + System.err.println(ming); | ||
45 | + } | ||
46 | + | ||
47 | + /** | ||
48 | + * 生成公钥和私钥 | ||
49 | + * | ||
50 | + * @throws NoSuchAlgorithmException | ||
51 | + */ | ||
52 | + public static HashMap<String, Object> getKeys() throws NoSuchAlgorithmException { | ||
53 | + HashMap<String, Object> map = new HashMap<String, Object>(); | ||
54 | + KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); | ||
55 | + keyPairGen.initialize(1024); | ||
56 | + KeyPair keyPair = keyPairGen.generateKeyPair(); | ||
57 | + RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); | ||
58 | + RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); | ||
59 | + map.put("public", publicKey); | ||
60 | + map.put("private", privateKey); | ||
61 | + return map; | ||
62 | + } | ||
63 | + | ||
64 | + /** | ||
65 | + * 使用模和指数生成RSA公钥 | ||
66 | + * 注意:【此代码用了默认补位方式,为RSA/None/PKCS1Padding,不同JDK默认的补位方式可能不同,如Android默认是RSA | ||
67 | + * /None/NoPadding】 | ||
68 | + * | ||
69 | + * @param modulus 模 | ||
70 | + * @param exponent 指数 | ||
71 | + * @return | ||
72 | + */ | ||
73 | + public static RSAPublicKey getPublicKey(String modulus, String exponent) { | ||
74 | + try { | ||
75 | + BigInteger b1 = new BigInteger(modulus); | ||
76 | + BigInteger b2 = new BigInteger(exponent); | ||
77 | + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); | ||
78 | + RSAPublicKeySpec keySpec = new RSAPublicKeySpec(b1, b2); | ||
79 | + return (RSAPublicKey) keyFactory.generatePublic(keySpec); | ||
80 | + } catch (Exception e) { | ||
81 | + e.printStackTrace(); | ||
82 | + return null; | ||
83 | + } | ||
84 | + } | ||
85 | + | ||
86 | + /** | ||
87 | + * 使用模和指数生成RSA私钥 | ||
88 | + * 注意:【此代码用了默认补位方式,为RSA/None/PKCS1Padding,不同JDK默认的补位方式可能不同,如Android默认是RSA | ||
89 | + * /None/NoPadding】 | ||
90 | + * | ||
91 | + * @param modulus 模 | ||
92 | + * @param exponent 指数 | ||
93 | + * @return | ||
94 | + */ | ||
95 | + public static RSAPrivateKey getPrivateKey(String modulus, String exponent) { | ||
96 | + try { | ||
97 | + BigInteger b1 = new BigInteger(modulus); | ||
98 | + BigInteger b2 = new BigInteger(exponent); | ||
99 | + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); | ||
100 | + RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(b1, b2); | ||
101 | + return (RSAPrivateKey) keyFactory.generatePrivate(keySpec); | ||
102 | + } catch (Exception e) { | ||
103 | + e.printStackTrace(); | ||
104 | + return null; | ||
105 | + } | ||
106 | + } | ||
107 | + | ||
108 | + /** | ||
109 | + * 公钥加密 | ||
110 | + * | ||
111 | + * @param data | ||
112 | + * @param publicKey | ||
113 | + * @return | ||
114 | + * @throws Exception | ||
115 | + */ | ||
116 | + public static String encryptByPublicKey(String data, RSAPublicKey publicKey) | ||
117 | + throws Exception { | ||
118 | + Cipher cipher = Cipher.getInstance("RSA"); | ||
119 | + cipher.init(Cipher.ENCRYPT_MODE, publicKey); | ||
120 | + // 模长 | ||
121 | + int key_len = publicKey.getModulus().bitLength() / 8; | ||
122 | + // 加密数据长度 <= 模长-11 | ||
123 | + String[] datas = splitString(data, key_len - 11); | ||
124 | + String mi = ""; | ||
125 | + //如果明文长度大于模长-11则要分组加密 | ||
126 | + for (String s : datas) { | ||
127 | + mi += bcd2Str(cipher.doFinal(s.getBytes())); | ||
128 | + } | ||
129 | + return mi; | ||
130 | + } | ||
131 | + | ||
132 | + /** | ||
133 | + * 私钥解密 | ||
134 | + * | ||
135 | + * @param data | ||
136 | + * @param privateKey | ||
137 | + * @return | ||
138 | + * @throws Exception | ||
139 | + */ | ||
140 | + public static String decryptByPrivateKey(String data, RSAPrivateKey privateKey) | ||
141 | + throws Exception { | ||
142 | + Cipher cipher = Cipher.getInstance("RSA"); | ||
143 | + cipher.init(Cipher.DECRYPT_MODE, privateKey); | ||
144 | + //模长 | ||
145 | + int key_len = privateKey.getModulus().bitLength() / 8; | ||
146 | + byte[] bytes = data.getBytes(); | ||
147 | + byte[] bcd = ASCII_To_BCD(bytes, bytes.length); | ||
148 | + System.err.println(bcd.length); | ||
149 | + //如果密文长度大于模长则要分组解密 | ||
150 | + String ming = ""; | ||
151 | + byte[][] arrays = splitArray(bcd, key_len); | ||
152 | + for (byte[] arr : arrays) { | ||
153 | + ming += new String(cipher.doFinal(arr)); | ||
154 | + } | ||
155 | + return ming; | ||
156 | + } | ||
157 | + | ||
158 | + /** | ||
159 | + * ASCII码转BCD码 | ||
160 | + */ | ||
161 | + public static byte[] ASCII_To_BCD(byte[] ascii, int asc_len) { | ||
162 | + byte[] bcd = new byte[asc_len / 2]; | ||
163 | + int j = 0; | ||
164 | + for (int i = 0; i < (asc_len + 1) / 2; i++) { | ||
165 | + bcd[i] = asc_to_bcd(ascii[j++]); | ||
166 | + bcd[i] = (byte) (((j >= asc_len) ? 0x00 : asc_to_bcd(ascii[j++])) + (bcd[i] << 4)); | ||
167 | + } | ||
168 | + return bcd; | ||
169 | + } | ||
170 | + | ||
171 | + public static byte asc_to_bcd(byte asc) { | ||
172 | + byte bcd; | ||
173 | + | ||
174 | + if ((asc >= '0') && (asc <= '9')) | ||
175 | + bcd = (byte) (asc - '0'); | ||
176 | + else if ((asc >= 'A') && (asc <= 'F')) | ||
177 | + bcd = (byte) (asc - 'A' + 10); | ||
178 | + else if ((asc >= 'a') && (asc <= 'f')) | ||
179 | + bcd = (byte) (asc - 'a' + 10); | ||
180 | + else | ||
181 | + bcd = (byte) (asc - 48); | ||
182 | + return bcd; | ||
183 | + } | ||
184 | + | ||
185 | + /** | ||
186 | + * BCD转字符串 | ||
187 | + */ | ||
188 | + public static String bcd2Str(byte[] bytes) { | ||
189 | + char temp[] = new char[bytes.length * 2], val; | ||
190 | + | ||
191 | + for (int i = 0; i < bytes.length; i++) { | ||
192 | + val = (char) (((bytes[i] & 0xf0) >> 4) & 0x0f); | ||
193 | + temp[i * 2] = (char) (val > 9 ? val + 'A' - 10 : val + '0'); | ||
194 | + | ||
195 | + val = (char) (bytes[i] & 0x0f); | ||
196 | + temp[i * 2 + 1] = (char) (val > 9 ? val + 'A' - 10 : val + '0'); | ||
197 | + } | ||
198 | + return new String(temp); | ||
199 | + } | ||
200 | + | ||
201 | + /** | ||
202 | + * 拆分字符串 | ||
203 | + */ | ||
204 | + public static String[] splitString(String string, int len) { | ||
205 | + int x = string.length() / len; | ||
206 | + int y = string.length() % len; | ||
207 | + int z = 0; | ||
208 | + if (y != 0) { | ||
209 | + z = 1; | ||
210 | + } | ||
211 | + String[] strings = new String[x + z]; | ||
212 | + String str = ""; | ||
213 | + for (int i = 0; i < x + z; i++) { | ||
214 | + if (i == x + z - 1 && y != 0) { | ||
215 | + str = string.substring(i * len, i * len + y); | ||
216 | + } else { | ||
217 | + str = string.substring(i * len, i * len + len); | ||
218 | + } | ||
219 | + strings[i] = str; | ||
220 | + } | ||
221 | + return strings; | ||
222 | + } | ||
223 | + | ||
224 | + /** | ||
225 | + * 拆分数组 | ||
226 | + */ | ||
227 | + public static byte[][] splitArray(byte[] data, int len) { | ||
228 | + int x = data.length / len; | ||
229 | + int y = data.length % len; | ||
230 | + int z = 0; | ||
231 | + if (y != 0) { | ||
232 | + z = 1; | ||
233 | + } | ||
234 | + byte[][] arrays = new byte[x + z][]; | ||
235 | + byte[] arr; | ||
236 | + for (int i = 0; i < x + z; i++) { | ||
237 | + arr = new byte[len]; | ||
238 | + if (i == x + z - 1 && y != 0) { | ||
239 | + System.arraycopy(data, i * len, arr, 0, y); | ||
240 | + } else { | ||
241 | + System.arraycopy(data, i * len, arr, 0, len); | ||
242 | + } | ||
243 | + arrays[i] = arr; | ||
244 | + } | ||
245 | + return arrays; | ||
246 | + } | ||
247 | +} |
-
Please register or login to post a comment