finished SSL&TCPConn

This commit is contained in:
free will committed 2021-06-29 20:50:46 +08:00
1 parent 9335c1e229
commit db2b45395e
9 files changed
+388 -22

No files matched your search

+108 -5
View File
@@ -2,9 +2,17 @@ package TCPNet;
import Security.BC_KeyManager;
import TCPNet.request.BaseRequest;
import TCPNet.response.BaseResponse;
import org.bouncycastle.crypto.InvalidCipherTextException;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.ArrayList;
import java.util.Random;
/*
@@ -21,10 +29,13 @@ class SSL_SetupMessage extends BaseRequest {
class SSL_Message extends BaseRequest{
int IsEncrypted;
int MType;
byte[] data;
byte[] Data;
String Pubkey="";
int Code=0;
}
class SSL_RespMessage extends BaseResponse {
int Code;
}
public class SSL {
// 是否加密
public static final int encrypted=0;
@@ -33,7 +44,20 @@ public class SSL {
public static final int normal=0;
public static final int setup=1;
public static final int resp=2;
// SSL_RespMessage类型
public static final int success=200;
public static final int bad_request=400;
public static final int not_authorized=403;
public static final int server_error=500;
/**
* 协商对称密钥
* @param conn
* @param pubKey 用户公钥
* @param key 无用参数,内含pubKey
* @param serverKey 服务器公钥
* @return 协商成功的对称密钥
*/
public static String sslSetup(Conn conn, String pubKey,
BC_KeyManager key,BC_KeyManager serverKey){
// 取一个十六位的密钥
@@ -64,7 +88,7 @@ public class SSL {
SSL_Message sslMessage=new SSL_Message();
sslMessage.IsEncrypted=encrypted;
sslMessage.MType=setup;
sslMessage.data=encData;
sslMessage.Data =encData;
String ms;
try {
ms=sm.toJson();
@@ -73,14 +97,93 @@ public class SSL {
return null;
}
// 将SSL_Message写给服务器
// 将SSL_Message写给服务器(内含:用户公钥、用户对称密钥)
if(!conn.writeV2(ms.getBytes(StandardCharsets.UTF_8))){
System.out.println("SSL write error");
return null;
}
//
// 读取服务器应答信息
byte[] resData=conn.readSSL();
if(resData==null){
System.out.println("SSL readSSL error");
return null;
}
return ;
// 用对称密钥解密应答信息
byte[] decRes;
try {
decRes=BC_KeyManager.SM4Decrypt(secretKey,resData);
} catch (IllegalBlockSizeException | InvalidKeyException | NoSuchProviderException
| NoSuchAlgorithmException | BadPaddingException | NoSuchPaddingException e) {
e.printStackTrace();
return null;
}
// 将解密信息转为Java对象
SSL_RespMessage resp=new SSL_RespMessage();
resp.unJson(decRes,resp);
// 判断应答信息的code
if(resp.Code!=success){
System.out.println("SSL setup failed, the server doesn't accept the request, " +
"and the status code is "+resp.Code);
return null;
}
return secretKey;
}
/**
* 使用密钥解密数据
* @param data
* @param role
* @param secretKey
* @return 泛型数组,依次存储:string(对称密钥) int(是否加密) int(code) byte[](解密数据)
*/
public static ArrayList sslDePacket(byte[] data, int role, String secretKey){
ArrayList result=new ArrayList();
result.add("");
result.add(not_encrypted);
result.add(400);
result.add(null);
// json转java对象
SSL_Message res=new SSL_Message();
res.unJson(data,res);
// 没有加密直接返回 200 和源数据res.Data
if(res.IsEncrypted==not_encrypted){
return result;
}else if(res.IsEncrypted==encrypted) {
// 加密 判断role
if(role==0){
// todo:根据解析出来的数据中的公钥ID从本地MAP获取公钥 对数据SM4解密
// todo: 这里是server应该事先的处理逻辑
System.out.println("sslDePacket error: role==0");
return result;
}else{
// 直接使用传入的密钥 对数据SM4解密
if(secretKey.equals("")){
System.out.println("sslDePacket error: secretKey == \"\"");
return result;
}
byte[] ans;
try {
ans= BC_KeyManager.SM4Decrypt(secretKey,res.Data);
} catch (IllegalBlockSizeException | NoSuchProviderException | InvalidKeyException | NoSuchAlgorithmException | BadPaddingException | NoSuchPaddingException e) {
e.printStackTrace();
return result;
}
if(ans==null){
System.out.println("SSL depacket failed, the secretKey can't use to decrypt the data");
return result;
}
result.set(1,encrypted);
result.set(2,200);
result.set(3,ans);
return result;
}
}else{
return result;
}
}
}