一、概述
微信推出了小程序,很多公司的客户端应用不仅具有了app、h5、还接入了小程序开发。但是,小程序中竟然没有提供java版本的加密数据解密算法。这着实让广大的java开发人员蛋疼。
我们下载的算法示例如下:
木有java!! 木有java!! 木有java!!
那么如何解决这个问题,我们一起来实现java版本的微信小程序加密数据解密算法。
二、实现java版本的微信小程序加密数据解密算法
1、创建项目
这里,我们创建一个maven工程,具体创建步骤略。
2、配置pom.xml
我们在pom.xml中加入如下配置。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<dependency>
<groupid>org.bouncycastle</groupid>
<artifactid>bcprov-jdk16</artifactid>
<version> 1.46 </version>
</dependency>
<dependency>
<groupid>commons-codec</groupid>
<artifactid>commons-codec</artifactid>
<version> 1.4 </version>
</dependency>
<dependency>
<groupid>net.sf.json-lib</groupid>
<artifactid>json-lib</artifactid>
<version> 2.2 . 3 </version>
<classifier>jdk15</classifier>
</dependency>
|
3、实现aes类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
package com.chwl.medical.crypto.wx;
import java.security.algorithmparameters;
import java.security.invalidalgorithmparameterexception;
import java.security.invalidkeyexception;
import java.security.key;
import java.security.nosuchalgorithmexception;
import java.security.nosuchproviderexception;
import java.security.security;
import javax.crypto.badpaddingexception;
import javax.crypto.cipher;
import javax.crypto.illegalblocksizeexception;
import javax.crypto.nosuchpaddingexception;
import javax.crypto.spec.ivparameterspec;
import javax.crypto.spec.secretkeyspec;
import org.bouncycastle.jce.provider.bouncycastleprovider;
/**
* aes加密
* @author liuyazhuang
*
*/
public class aes {
public static boolean initialized = false ;
/**
* aes解密
*
* @param content
* 密文
* @return
* @throws invalidalgorithmparameterexception
* @throws nosuchproviderexception
*/
public byte [] decrypt( byte [] content, byte [] keybyte, byte [] ivbyte) throws invalidalgorithmparameterexception {
initialize();
try {
cipher cipher = cipher.getinstance( "aes/cbc/pkcs7padding" );
key skeyspec = new secretkeyspec(keybyte, "aes" );
cipher.init(cipher.decrypt_mode, skeyspec, generateiv(ivbyte)); // 初始化
byte [] result = cipher.dofinal(content);
return result;
} catch (nosuchalgorithmexception e) {
e.printstacktrace();
} catch (nosuchpaddingexception e) {
e.printstacktrace();
} catch (invalidkeyexception e) {
e.printstacktrace();
} catch (illegalblocksizeexception e) {
e.printstacktrace();
} catch (badpaddingexception e) {
e.printstacktrace();
} catch (nosuchproviderexception e) {
// todo auto-generated catch block
e.printstacktrace();
} catch (exception e) {
// todo auto-generated catch block
e.printstacktrace();
}
return null ;
}
public static void initialize() {
if (initialized)
return ;
security.addprovider( new bouncycastleprovider());
initialized = true ;
}
// 生成iv
public static algorithmparameters generateiv( byte [] iv) throws exception {
algorithmparameters params = algorithmparameters.getinstance( "aes" );
params.init( new ivparameterspec(iv));
return params;
}
}
|
4、实现wxpkcs7encoder类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
package com.chwl.medical.crypto.wx;
import java.nio.charset.charset;
import java.util.arrays;
/**
* 微信小程序加解密
* @author liuyazhuang
*
*/
public class wxpkcs7encoder {
private static final charset charset = charset.forname( "utf-8" );
private static final int block_size = 32 ;
/**
* 获得对明文进行补位填充的字节.
*
* @param count
* 需要进行填充补位操作的明文字节个数
* @return 补齐用的字节数组
*/
public static byte [] encode( int count) {
// 计算需要填充的位数
int amounttopad = block_size - (count % block_size);
if (amounttopad == 0 ) {
amounttopad = block_size;
}
// 获得补位所用的字符
char padchr = chr(amounttopad);
string tmp = new string();
for ( int index = 0 ; index < amounttopad; index++) {
tmp += padchr;
}
return tmp.getbytes(charset);
}
/**
* 删除解密后明文的补位字符
*
* @param decrypted
* 解密后的明文
* @return 删除补位字符后的明文
*/
public static byte [] decode( byte [] decrypted) {
int pad = decrypted[decrypted.length - 1 ];
if (pad < 1 || pad > 32 ) {
pad = 0 ;
}
return arrays.copyofrange(decrypted, 0 , decrypted.length - pad);
}
/**
* 将数字转化成ascii码对应的字符,用于对明文进行补码
*
* @param a
* 需要转化的数字
* @return 转化得到的字符
*/
public static char chr( int a) {
byte target = ( byte ) (a & 0xff );
return ( char ) target;
}
}
|
5、实现wxcore类
这个类主要是对具体算法的封装,统一对外提供方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
package com.chwl.medical.crypto.wx;
import org.apache.commons.codec.binary.base64;
import net.sf.json.jsonobject;
/**
* 封装对外访问方法
* @author liuyazhuang
*
*/
public class wxcore {
private static final string watermark = "watermark" ;
private static final string appid = "appid" ;
/**
* 解密数据
* @return
* @throws exception
*/
public static string decrypt(string appid, string encrypteddata, string sessionkey, string iv){
string result = "" ;
try {
aes aes = new aes();
byte [] resultbyte = aes.decrypt(base64.decodebase64(encrypteddata), base64.decodebase64(sessionkey), base64.decodebase64(iv));
if ( null != resultbyte && resultbyte.length > 0 ){
result = new string(wxpkcs7encoder.decode(resultbyte));
jsonobject jsonobject = jsonobject.fromobject(result);
string decryptappid = jsonobject.getjsonobject(watermark).getstring(appid);
if (!appid.equals(decryptappid)){
result = "" ;
}
}
} catch (exception e) {
result = "" ;
e.printstacktrace();
}
return result;
}
public static void main(string[] args) throws exception{
string appid = "wx4f4bc4dec97d474b" ;
string encrypteddata = "ciylu1aw2kjvrjmdj8ykliajtp4gsmzmqmrzoog2xrdcvsnximxfufnstngtyags9ut5gera0w4otob1wt7fjlac+onpdbb+3hvbjsrgv+4lgoetkuqz6oystslq142dncuabnpgbzlooomb231qmm85d2/fv6chevvxvqp8hkue1pooftnetpyxvlw1zao6/1xx1coxfvrc2d7ul/lmhinnlxuacjxwu0fjpxfz/yqyzbibzd6wuftif9grhpon/hz7sal8xz+w//frauid1oksqaqx4cms8loddcqhulw4ucetdf96jcr3g0gfrk4pc7e/r7z6xnrxd2uieorgj5ef7b1pjayb6y5anahqz9j6nkebvb4dnnlivwsgarns/8wr2sirs7mnacwtyrgvt9ts8p12pkfdlqytopnhr1vf7xjfhqlvsajdnikdymyvoklarv85ifvunyzo0ikxsyl7jcujcpog20f0a04cowfneqaggwd5oa+t8yo5hzuydb/xcxxmk01epqoyuxinew==" ;
string sessionkey = "tiihtnczf5v6akryjweuhq==" ;
string iv = "r7bxxkklb8qrsnn05n0qia==" ;
system.out.println(decrypt(appid, encrypteddata, sessionkey, iv));
}
}
|
三、测试
1、运行java版微信小程序加密数据解密算法
这里我们就直接运行wxcore类的main方法,这里的测试数据都是从python版微信小程序加密数据解密算法的示例程序中提出来的。我们的运行结果如下:
2、运行python版微信小程序加密数据解密算法
这里我们在python环境中直接运行微信官方提供的python版小程序加密数据解密算法,结果如下:
通过对比以上结果可知,我们自行使用java实现的java版微信小程序加密数据解密算法与微信官方提供的python版小程序加密数据解密算法结果一致。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/l1028386804/article/details/79450115