Skip to content

Commit

Permalink
新增:HttpServer请求/应答报文进行国密SM4对称加密传输 【配套SmsF微信小程序】
Browse files Browse the repository at this point in the history
  • Loading branch information
pppscn committed Oct 21, 2022
1 parent a624ca5 commit 538f440
Show file tree
Hide file tree
Showing 21 changed files with 621 additions and 185 deletions.
3 changes: 3 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,9 @@ dependencies {
//HTTP服务器:https://github.com/yanzhenjie/AndServer
implementation 'cn.ppps.andserver:api:2.1.11'
kapt 'cn.ppps.andserver:processor:2.1.11'

//国密算法SM4 的JAVA实现(基于BC实现)
api "org.bouncycastle:bcprov-jdk15on:1.69"
}
//自动添加X-Library依赖
apply from: 'x-library.gradle'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ import com.xuexiang.xui.widget.actionbar.TitleBar
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
import com.xuexiang.xutil.XUtil
import com.xuexiang.xutil.data.ConvertTools


@Suppress("PrivatePropertyName", "PropertyName")
@Page(name = "主动控制·客户端")
Expand Down Expand Up @@ -123,26 +125,34 @@ class ClientFragment : BaseFragment<FragmentClientBinding?>(), View.OnClickListe
safetyMeasuresId = R.id.rb_safety_measures_rsa
binding!!.tvSignKey.text = getString(R.string.public_key)
}
3 -> {
safetyMeasuresId = R.id.rb_safety_measures_sm4
binding!!.tvSignKey.text = getString(R.string.sm4_key)
}
else -> {
binding!!.layoutSignKey.visibility = View.GONE
}
}
binding!!.rgSafetyMeasures.check(safetyMeasuresId)
binding!!.rgSafetyMeasures.setOnCheckedChangeListener { _: RadioGroup?, checkedId: Int ->
var safetyMeasures = 0
binding!!.layoutSignKey.visibility = View.GONE
binding!!.layoutSignKey.visibility = View.VISIBLE
when (checkedId) {
R.id.rb_safety_measures_sign -> {
safetyMeasures = 1
binding!!.tvSignKey.text = getString(R.string.sign_key)
binding!!.layoutSignKey.visibility = View.VISIBLE
}
R.id.rb_safety_measures_rsa -> {
safetyMeasures = 2
binding!!.tvSignKey.text = getString(R.string.public_key)
binding!!.layoutSignKey.visibility = View.VISIBLE
}
else -> {}
R.id.rb_safety_measures_sm4 -> {
safetyMeasures = 3
binding!!.tvSignKey.text = getString(R.string.sm4_key)
}
else -> {
binding!!.layoutSignKey.visibility = View.GONE
}
}
HttpServerUtils.clientSafetyMeasures = safetyMeasures
}
Expand Down Expand Up @@ -195,6 +205,10 @@ class ClientFragment : BaseFragment<FragmentClientBinding?>(), View.OnClickListe
safetyMeasuresId = R.id.rb_safety_measures_rsa
binding!!.tvSignKey.text = getString(R.string.public_key)
}
"3" -> {
safetyMeasuresId = R.id.rb_safety_measures_sm4
binding!!.tvSignKey.text = getString(R.string.sm4_key)
}
else -> {
binding!!.tvSignKey.visibility = View.GONE
binding!!.etSignKey.visibility = View.GONE
Expand Down Expand Up @@ -254,8 +268,8 @@ class ClientFragment : BaseFragment<FragmentClientBinding?>(), View.OnClickListe
msgMap["timestamp"] = timestamp

val clientSignKey = HttpServerUtils.clientSignKey.toString()
if ((HttpServerUtils.clientSafetyMeasures == 1 || HttpServerUtils.clientSafetyMeasures == 2) && TextUtils.isEmpty(clientSignKey)) {
if (needToast) XToastUtils.error("请输入签名密钥或RSA公钥")
if (HttpServerUtils.clientSafetyMeasures != 0 && TextUtils.isEmpty(clientSignKey)) {
if (needToast) XToastUtils.error("请输入签名密钥/RSA公钥/SM4密钥")
return
}

Expand All @@ -273,20 +287,37 @@ class ClientFragment : BaseFragment<FragmentClientBinding?>(), View.OnClickListe
.timeOut((SettingUtils.requestTimeout * 1000).toLong()) //超时时间10s
.cacheMode(CacheMode.NO_CACHE).timeStamp(true)

if (HttpServerUtils.clientSafetyMeasures == 2) {
val publicKey = RSACrypt.getPublicKey(HttpServerUtils.clientSignKey.toString())
try {
requestMsg = Base64.encode(requestMsg.toByteArray())
requestMsg = RSACrypt.encryptByPublicKey(requestMsg, publicKey)
Log.i(TAG, "requestMsg: $requestMsg")
} catch (e: Exception) {
if (needToast) XToastUtils.error(ResUtils.getString(R.string.request_failed) + e.message)
e.printStackTrace()
return
when (HttpServerUtils.clientSafetyMeasures) {
2 -> {
try {
val publicKey = RSACrypt.getPublicKey(HttpServerUtils.clientSignKey.toString())
requestMsg = Base64.encode(requestMsg.toByteArray())
requestMsg = RSACrypt.encryptByPublicKey(requestMsg, publicKey)
Log.i(TAG, "requestMsg: $requestMsg")
} catch (e: Exception) {
if (needToast) XToastUtils.error(ResUtils.getString(R.string.request_failed) + e.message)
e.printStackTrace()
return
}
postRequest.upString(requestMsg)
}
3 -> {
try {
val sm4Key = ConvertTools.hexStringToByteArray(HttpServerUtils.clientSignKey.toString())
//requestMsg = Base64.encode(requestMsg.toByteArray())
val encryptCBC = SM4Crypt.encrypt(requestMsg.toByteArray(), sm4Key)
requestMsg = ConvertTools.bytes2HexString(encryptCBC)
Log.i(TAG, "requestMsg: $requestMsg")
} catch (e: Exception) {
if (needToast) XToastUtils.error(ResUtils.getString(R.string.request_failed) + e.message)
e.printStackTrace()
return
}
postRequest.upString(requestMsg)
}
else -> {
postRequest.upJson(requestMsg)
}
postRequest.upString(requestMsg)
} else {
postRequest.upJson(requestMsg)
}

if (needToast) mCountDownHelper?.start()
Expand All @@ -304,6 +335,11 @@ class ClientFragment : BaseFragment<FragmentClientBinding?>(), View.OnClickListe
val publicKey = RSACrypt.getPublicKey(HttpServerUtils.clientSignKey.toString())
json = RSACrypt.decryptByPublicKey(json, publicKey)
json = String(Base64.decode(json))
} else if (HttpServerUtils.clientSafetyMeasures == 3) {
val sm4Key = ConvertTools.hexStringToByteArray(HttpServerUtils.clientSignKey.toString())
val encryptCBC = ConvertTools.hexStringToByteArray(json)
val decryptCBC = SM4Crypt.decrypt(encryptCBC, sm4Key)
json = String(decryptCBC)
}
val resp: BaseResponse<ConfigData> = Gson().fromJson(json, object : TypeToken<BaseResponse<ConfigData>>() {}.type)
if (resp.code == 200) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import com.xuexiang.xui.widget.button.SmoothCheckBox
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog
import com.xuexiang.xui.widget.picker.XSeekBar
import com.xuexiang.xutil.app.ServiceUtils
import com.xuexiang.xutil.data.ConvertTools
import com.xuexiang.xutil.net.NetworkUtils
import com.xuexiang.xutil.system.ClipboardUtils
import java.io.File
Expand Down Expand Up @@ -92,6 +93,10 @@ class ServerFragment : BaseFragment<FragmentServerBinding?>(), View.OnClickListe
binding!!.layoutPrivateKey.visibility = View.VISIBLE
binding!!.layoutPublicKey.visibility = View.VISIBLE
}
3 -> {
safetyMeasuresId = R.id.rb_safety_measures_sm4
binding!!.layoutSm4Key.visibility = View.VISIBLE
}
else -> {}
}
binding!!.rgSafetyMeasures.check(safetyMeasuresId)
Expand All @@ -101,6 +106,7 @@ class ServerFragment : BaseFragment<FragmentServerBinding?>(), View.OnClickListe
binding!!.layoutTimeTolerance.visibility = View.GONE
binding!!.layoutPrivateKey.visibility = View.GONE
binding!!.layoutPublicKey.visibility = View.GONE
binding!!.layoutSm4Key.visibility = View.GONE
when (checkedId) {
R.id.rb_safety_measures_sign -> {
safetyMeasures = 1
Expand All @@ -112,11 +118,26 @@ class ServerFragment : BaseFragment<FragmentServerBinding?>(), View.OnClickListe
binding!!.layoutPrivateKey.visibility = View.VISIBLE
binding!!.layoutPublicKey.visibility = View.VISIBLE
}
R.id.rb_safety_measures_sm4 -> {
safetyMeasures = 3
binding!!.layoutSm4Key.visibility = View.VISIBLE
}
else -> {}
}
HttpServerUtils.safetyMeasures = safetyMeasures
}

//SM4密钥
binding!!.btnSm4Key.setOnClickListener(this)
binding!!.etSm4Key.setText(HttpServerUtils.serverSm4Key)
binding!!.etSm4Key.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
override fun afterTextChanged(s: Editable) {
HttpServerUtils.serverSm4Key = binding!!.etSm4Key.text.toString().trim()
}
})

//RSA公私钥
binding!!.btnCopyPublicKey.setOnClickListener(this)
binding!!.btnGenerateKey.setOnClickListener(this)
Expand Down Expand Up @@ -221,6 +242,13 @@ class ServerFragment : BaseFragment<FragmentServerBinding?>(), View.OnClickListe
}
refreshButtonText()
}
R.id.btn_sm4_key -> {
val key = ConvertTools.bytes2HexString(SM4Crypt.createSM4Key())
println("SM4密钥:$key")
ClipboardUtils.copyText(key)
binding!!.etSm4Key.setText(key)
XToastUtils.info(getString(R.string.sign_key_tips))
}
R.id.btn_generate_key -> {
val generator = KeyPairGenerator.getInstance("RSA") //密钥生成器
generator.initialize(2048)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import com.xuexiang.xrouter.utils.TextUtils
import com.xuexiang.xui.utils.ResUtils
import com.xuexiang.xui.widget.actionbar.TitleBar
import com.xuexiang.xui.widget.grouplist.XUIGroupListView
import com.xuexiang.xutil.data.ConvertTools

@Suppress("PropertyName")
@Page(name = "远程查电量")
Expand Down Expand Up @@ -67,20 +68,37 @@ class BatteryQueryFragment : BaseFragment<FragmentClientBatteryQueryBinding?>()
.cacheMode(CacheMode.NO_CACHE)
.timeStamp(true)

if (HttpServerUtils.clientSafetyMeasures == 2) {
val publicKey = RSACrypt.getPublicKey(HttpServerUtils.clientSignKey.toString())
try {
requestMsg = Base64.encode(requestMsg.toByteArray())
requestMsg = RSACrypt.encryptByPublicKey(requestMsg, publicKey)
Log.i(TAG, "requestMsg: $requestMsg")
} catch (e: Exception) {
XToastUtils.error(ResUtils.getString(R.string.request_failed) + e.message)
e.printStackTrace()
return
when (HttpServerUtils.clientSafetyMeasures) {
2 -> {
try {
val publicKey = RSACrypt.getPublicKey(HttpServerUtils.clientSignKey.toString())
requestMsg = Base64.encode(requestMsg.toByteArray())
requestMsg = RSACrypt.encryptByPublicKey(requestMsg, publicKey)
Log.i(TAG, "requestMsg: $requestMsg")
} catch (e: Exception) {
XToastUtils.error(ResUtils.getString(R.string.request_failed) + e.message)
e.printStackTrace()
return
}
postRequest.upString(requestMsg)
}
3 -> {
try {
val sm4Key = ConvertTools.hexStringToByteArray(HttpServerUtils.clientSignKey.toString())
//requestMsg = Base64.encode(requestMsg.toByteArray())
val encryptCBC = SM4Crypt.encrypt(requestMsg.toByteArray(), sm4Key)
requestMsg = ConvertTools.bytes2HexString(encryptCBC)
Log.i(TAG, "requestMsg: $requestMsg")
} catch (e: Exception) {
XToastUtils.error(ResUtils.getString(R.string.request_failed) + e.message)
e.printStackTrace()
return
}
postRequest.upString(requestMsg)
}
else -> {
postRequest.upJson(requestMsg)
}
postRequest.upString(requestMsg)
} else {
postRequest.upJson(requestMsg)
}

postRequest.execute(object : SimpleCallBack<String>() {
Expand All @@ -96,6 +114,11 @@ class BatteryQueryFragment : BaseFragment<FragmentClientBatteryQueryBinding?>()
val publicKey = RSACrypt.getPublicKey(HttpServerUtils.clientSignKey.toString())
json = RSACrypt.decryptByPublicKey(json, publicKey)
json = String(Base64.decode(json))
} else if (HttpServerUtils.clientSafetyMeasures == 3) {
val sm4Key = ConvertTools.hexStringToByteArray(HttpServerUtils.clientSignKey.toString())
val encryptCBC = ConvertTools.hexStringToByteArray(json)
val decryptCBC = SM4Crypt.decrypt(encryptCBC, sm4Key)
json = String(decryptCBC)
}
val resp: BaseResponse<BatteryInfo> = Gson().fromJson(json, object : TypeToken<BaseResponse<BatteryInfo>>() {}.type)
if (resp.code == 200) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import com.xuexiang.xui.utils.ResUtils
import com.xuexiang.xui.utils.SnackbarUtils
import com.xuexiang.xui.widget.actionbar.TitleBar
import com.xuexiang.xui.widget.searchview.MaterialSearchView
import com.xuexiang.xutil.data.ConvertTools
import com.xuexiang.xutil.data.DateUtils
import com.xuexiang.xutil.system.ClipboardUtils
import me.samlss.broccoli.Broccoli
Expand Down Expand Up @@ -216,20 +217,37 @@ class CallQueryFragment : BaseFragment<FragmentClientCallQueryBinding?>() {
.cacheMode(CacheMode.NO_CACHE)
.timeStamp(true)

if (HttpServerUtils.clientSafetyMeasures == 2) {
val publicKey = RSACrypt.getPublicKey(HttpServerUtils.clientSignKey.toString())
try {
requestMsg = Base64.encode(requestMsg.toByteArray())
requestMsg = RSACrypt.encryptByPublicKey(requestMsg, publicKey)
Log.i(TAG, "requestMsg: $requestMsg")
} catch (e: Exception) {
XToastUtils.error(ResUtils.getString(R.string.request_failed) + e.message)
e.printStackTrace()
return
when (HttpServerUtils.clientSafetyMeasures) {
2 -> {
val publicKey = RSACrypt.getPublicKey(HttpServerUtils.clientSignKey.toString())
try {
requestMsg = Base64.encode(requestMsg.toByteArray())
requestMsg = RSACrypt.encryptByPublicKey(requestMsg, publicKey)
Log.i(TAG, "requestMsg: $requestMsg")
} catch (e: Exception) {
XToastUtils.error(ResUtils.getString(R.string.request_failed) + e.message)
e.printStackTrace()
return
}
postRequest.upString(requestMsg)
}
3 -> {
try {
val sm4Key = ConvertTools.hexStringToByteArray(HttpServerUtils.clientSignKey.toString())
//requestMsg = Base64.encode(requestMsg.toByteArray())
val encryptCBC = SM4Crypt.encrypt(requestMsg.toByteArray(), sm4Key)
requestMsg = ConvertTools.bytes2HexString(encryptCBC)
Log.i(TAG, "requestMsg: $requestMsg")
} catch (e: Exception) {
XToastUtils.error(ResUtils.getString(R.string.request_failed) + e.message)
e.printStackTrace()
return
}
postRequest.upString(requestMsg)
}
else -> {
postRequest.upJson(requestMsg)
}
postRequest.upString(requestMsg)
} else {
postRequest.upJson(requestMsg)
}

postRequest.execute(object : SimpleCallBack<String>() {
Expand All @@ -245,6 +263,11 @@ class CallQueryFragment : BaseFragment<FragmentClientCallQueryBinding?>() {
val publicKey = RSACrypt.getPublicKey(HttpServerUtils.clientSignKey.toString())
json = RSACrypt.decryptByPublicKey(json, publicKey)
json = String(Base64.decode(json))
} else if (HttpServerUtils.clientSafetyMeasures == 3) {
val sm4Key = ConvertTools.hexStringToByteArray(HttpServerUtils.clientSignKey.toString())
val encryptCBC = ConvertTools.hexStringToByteArray(json)
val decryptCBC = SM4Crypt.decrypt(encryptCBC, sm4Key)
json = String(decryptCBC)
}
val resp: BaseResponse<List<CallInfo>?> = Gson().fromJson(json, object : TypeToken<BaseResponse<List<CallInfo>?>>() {}.type)
if (resp.code == 200) {
Expand Down
Loading

0 comments on commit 538f440

Please sign in to comment.