实现“实现对签名推式包的替换编码

This commit is contained in:
free will
2021-11-01 23:39:02 +08:00
parent b6e54b34c4
commit 221c73034f
5 changed files with 505 additions and 2 deletions
+22
View File
@@ -3,8 +3,10 @@ package security;
import component.Signature; import component.Signature;
import encoding.Block; import encoding.Block;
import encoding.SelfEncodingBase; import encoding.SelfEncodingBase;
import minsecurity.crypto.AsymKeyException;
import minsecurity.identity.Identity; import minsecurity.identity.Identity;
import minsecurity.identity.IdentityException; import minsecurity.identity.IdentityException;
import org.bouncycastle.crypto.CryptoException;
import packet.CPacket; import packet.CPacket;
import packet.Data; import packet.Data;
import packet.Interest; import packet.Interest;
@@ -16,6 +18,7 @@ import javax.crypto.NoSuchPaddingException;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException; import java.security.NoSuchProviderException;
import java.util.Arrays;
/* /*
* @Author: hongyu guo * @Author: hongyu guo
@@ -260,6 +263,25 @@ public class KeyChain {
this.sign(data.minPacket); this.sign(data.minPacket);
} }
/**
* 对已经合并好的标识区和只读区进行签名
* @param mergeArray 原文:已经合并好的标识区和只读区
* @return 密文
*/
public byte[] signBytes(byte[] mergeArray) throws Exception {
return this.currentIdentity.sign(mergeArray);
}
/**
* 验证签名
* @param mergeArray 原文
* @param digest 密文
* @return
*/
public boolean verifyBytes(byte[] mergeArray,byte[] digest) throws Exception {
return this.currentIdentity.verify(mergeArray,digest);
}
/** /**
* 验证一个MIN网络包中的签名是否有效 * 验证一个MIN网络包中的签名是否有效
* @param minPacket * @param minPacket
@@ -31,10 +31,10 @@ public class RegisterPrefixHelperTest {
// 初始化KeyChain // 初始化KeyChain
// KeyChain keyChain=new KeyChain(); // KeyChain keyChain=new KeyChain();
RegisterPrefixHelper helper=new RegisterPrefixHelper(); // RegisterPrefixHelper helper=new RegisterPrefixHelper();
KeyManagerExample.INSTANCE.initKeyChain("/wefree/test","D://"); KeyManagerExample.INSTANCE.initKeyChain("/wefree/test","D://");
face.setKeyChain(KeyManagerExample.INSTANCE.getKeyChain()); face.setKeyChain(KeyManagerExample.INSTANCE.getKeyChain());
helper.registerPrefix(identifier,face,KeyManagerExample.INSTANCE.getKeyChain()); // helper.registerPrefix(identifier,face,KeyManagerExample.INSTANCE.getKeyChain());
// 测试发包速率 // 测试发包速率
Identifier serverIden = null; Identifier serverIden = null;
+167
View File
@@ -1,5 +1,16 @@
import component.ComponentException;
import component.Identifier;
import encoding.TLV;
import encoding.TLVException;
import encoding.VlInt;
import encoding.VlIntException;
import minsecurity.crypto.sm2.SM2KeyPair; import minsecurity.crypto.sm2.SM2KeyPair;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils; import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import packet.CPacket;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Random;
/* /*
* @Author: hongyu guo * @Author: hongyu guo
@@ -17,4 +28,160 @@ public class testPrivate {
System.out.println("a = " + a); System.out.println("a = " + a);
System.out.println("private key = " + ByteUtils.toHexString(sm2KeyPair.getSm2PrivateKey().getBytes())); System.out.println("private key = " + ByteUtils.toHexString(sm2KeyPair.getSm2PrivateKey().getBytes()));
} }
public static String getFixLenthString(int strLength) {
Random rm = new Random();
// 获得随机数
double pross = (1 + rm.nextDouble()) * Math.pow(10, strLength);
// 将获得的获得随机数转化为字符串
String fixLenthString = String.valueOf(pross);
// 返回固定的长度的随机数
return fixLenthString.substring(1, strLength + 1);
}
public static String getAll0String() {
return new String("0000000000");
}
public static void main(String[] args) throws VlIntException {
// 测试vlint
VlInt a=new VlInt(1200);
System.out.println("1200 is bytes: "+ Arrays.toString(a.getVlIntBytes()));
System.out.println("1200 len: "+a.size());
a=new VlInt(1204);
System.out.println("1204 is bytes: "+ Arrays.toString(a.getVlIntBytes()));
System.out.println("1204 len: "+a.size());
a=new VlInt(1298);
System.out.println("1298 is bytes: "+ Arrays.toString(a.getVlIntBytes()));
System.out.println("1298 len: "+a.size());
byte[] matchArray=new byte[]{(byte)11,(byte) 0,(byte) 48,(byte) 48,(byte) 48,(byte) 48,(byte) 48};
System.out.println(Arrays.toString(matchArray));
System.out.println(findThePos(matchArray));
int seq=11;
Identifier clientIden = null;
try {
clientIden=new Identifier("/min/gdcni9/default/"+seq);
} catch (ComponentException e) {
e.printStackTrace();
return;
}
Identifier serverIden = null;
try {
// serverIden=new Identifier("/hk/vpnserver/10/"+getFixLenthString(10));
serverIden=new Identifier("/hk/vpnserver/10/"+getAll0String());
} catch (ComponentException e) {
e.printStackTrace();
return;
}
CPacket cPacket=new CPacket();
cPacket.setSrcIdentifier(clientIden);
cPacket.setDstIdentifier(serverIden);
cPacket.ttl.setTtl(64);
byte[] pay=new byte[10];
cPacket.payload.setValue(pay);
cPacket.encodeSelf(); // 先编码!!!减少发包阻塞。
System.out.println(Arrays.toString(cPacket.getRawData()));
System.out.println(cPacket.getRawData().length);
// byte[] ta=cPacket.getRawData();
// System.out.println("ta len: "+ta.length);
int pos=findThePos(cPacket.getRawData());
// System.out.println("pos: "+pos);
// byte[] newData=replaceRandomPos(cPacket.getRawData(),pos);
// System.out.println("替换结果: "+ Arrays.toString(newData));
byte[] newData=replaceRandomPos(cPacket.getRawData(),pos,pos+10,1200);
System.out.println("替换结果: "+ Arrays.toString(newData));
}
// [5, 108,
// 50, 85, 102, 36,
// 101, 34, 100, 2, 0, 47,
// 100, 4, 0, 109, 105, 110, 100, 7, 0, 103,
//100, 99, 110, 105, 57, 100, 8, 0,
//100, 101, 102, 97, 117, 108, 116,
//100, 3, 0, 49, 49, 102, 45, 101, 43,
//100, 2, 0, 47, 100, 3, 0, 104, 107,
//100, 10, 0, 118, 112, 110, 115, 101, 114, 118, 101, 114,
//100, 3, 0, 49, 48,
//100, 11, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 100, 2, 4, 10, 52, 12, -52, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 5, 55, 3, -44, 1, 64
// 要找的字符数组是:100, 11, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48
// 分析其特点,找到连续的五个48,且前面依次是11、0,即可。假定是10个连续随机数
public static int findThePos(byte[] targetArray){
byte[] matchArray=new byte[]{(byte)11,(byte) 0,(byte) 48};
System.out.println("target: "+Arrays.toString(targetArray));
System.out.println("match: "+ Arrays.toString(matchArray));
for (int i = 0; i < (targetArray.length-7); i++) {
if((targetArray[i]==matchArray[0])
&& (targetArray[i+1]==matchArray[1])
&& (targetArray[i+2]==matchArray[2])
&& (targetArray[i+3]==matchArray[2])
&& (targetArray[i+4]==matchArray[2])
&& (targetArray[i+5]==matchArray[2])
&& (targetArray[i+6]==matchArray[2])){
System.out.println("我中了");
return i+2;
}
}
return -1;
}
public static byte[] replaceRandomPos(byte[] targetArray,int pos){
System.arraycopy(getFixLenthString(10).getBytes(StandardCharsets.UTF_8),0,targetArray,pos,10);
return targetArray;
}
public static byte[] replaceRandomPos(byte[] targetArray,int randomPos,int readPos,int payloadLen)
throws VlIntException {
System.out.println("ttt1");
// 先读取原头部的总长度
VlInt oldLen;
try {
oldLen= TLV.readVarNumber(targetArray,new VlInt(1));
} catch (TLVException e) {
e.printStackTrace();
return null;
}
System.out.println("ttt2");
// 计算需要总长度
VlInt payLen=new VlInt(payloadLen); // 负载长度
VlInt readLen=new VlInt(payloadLen+payLen.size()+1); // 可读区长度
VlInt packetLen=new VlInt((readPos-1-oldLen.size())
+(readLen.getVlIntValue2Int()+readLen.size()+1)
+7);// 通用包长度
System.out.println("pk len: "+packetLen);
int allLen=(packetLen.getVlIntValue2Int()+packetLen.size()+1)-7-payloadLen; // 总长度
System.out.println("ttt3");
// 构造最后的返回数组
byte[] totalData=new byte[allLen];
// 1. 拷贝包头
totalData[0]=(byte)5;
System.arraycopy(packetLen.getVlIntBytes(),0,totalData,1,packetLen.size());
System.out.println("ttt4");
// 2. 拷贝随机段之前的数据(固定标识字段)
System.arraycopy(targetArray,1+oldLen.size(),totalData,1+packetLen.size(),
randomPos-1-oldLen.size());
System.out.println("ttt5");
System.out.println("readpos: "+readPos);
System.out.println("packetLen.size: "+packetLen.size());
System.out.println("oldlen.size: "+oldLen.size());
// 3. 拷贝随机段(目的标识的活动字段)
System.arraycopy(getFixLenthString(10).getBytes(StandardCharsets.UTF_8),
0,totalData,randomPos+packetLen.size()-oldLen.size(),10);
System.out.println("ttt6");
// 4. 拷贝负载区头部
totalData[readPos+packetLen.size()-oldLen.size()]=(byte)52;
System.arraycopy(readLen.getVlIntBytes(),0,totalData,
readPos+packetLen.size()-oldLen.size()+1,readLen.size());
totalData[readPos+packetLen.size()-oldLen.size()+1+readLen.size()]=(byte)204;
System.arraycopy(payLen.getVlIntBytes(),0,totalData,
readPos+packetLen.size()-oldLen.size()+1+readLen.size()+1,payLen.size());
System.out.println("ttt7");
int newRandomPos=randomPos-oldLen.size()+packetLen.size();
System.out.println("pos: "+randomPos);
System.out.println("newpos: "+newRandomPos);
return totalData;
}
} }
@@ -0,0 +1,314 @@
import component.ComponentException;
import component.Identifier;
import encoding.TLV;
import encoding.TLVException;
import encoding.VlInt;
import encoding.VlIntException;
import examples.KeyManagerExample;
import org.bouncycastle.crypto.CryptoException;
import packet.CPacket;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
/*
* @Author: Wang Feng
* @Description: 测试带签名的打印信息
* @Version: 1.0.0
* @Date: 11:00 2021/10/28
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public class testQuickEncodeWithSignature {
public static void main(String[] args){
Identifier clientIden = null;
try {
clientIden=new Identifier("/wefree/test");
} catch (ComponentException e) {
e.printStackTrace();
return;
}
Identifier serverIden = null;
try {
// serverIden=new Identifier("/hk/vpnserver/10/"+getFixLenthString(10));
serverIden=new Identifier("/hk/vpnserver/10/"+testPrivate.getAll0String());
} catch (ComponentException e) {
e.printStackTrace();
return;
}
CPacket cPacket=new CPacket();
cPacket.setSrcIdentifier(clientIden);
cPacket.setDstIdentifier(serverIden);
cPacket.ttl.setTtl(64);
byte[] pay=new byte[10];
cPacket.payload.setValue(pay);
cPacket.encodeSelf(); // 先编码!!!减少发包阻塞。
System.out.println("签名前: "+Arrays.toString(cPacket.getRawData()));
System.out.println("签名前len: "+cPacket.getRawData().length);
// byte[] ta=cPacket.getRawData();
// System.out.println("ta len: "+ta.length);
int pos=testPrivate.findThePos(cPacket.getRawData());
System.out.println("pos: "+pos);
// byte[] newData=replaceRandomPos(cPacket.getRawData(),pos);
// System.out.println("替换结果: "+ Arrays.toString(newData));
// byte[] newData=replaceRandomPos(cPacket.getRawData(),pos,pos+10,1200);
// System.out.println("替换结果: "+ Arrays.toString(newData));
// 签名CPacket
KeyManagerExample.INSTANCE.initKeyChain("/wefree/test","D://");
try {
KeyManagerExample.INSTANCE.getKeyChain().signCPacket(cPacket);
} catch (Exception e) {
e.printStackTrace();
}
cPacket.encodeSelf();
// 打印分析签名字段
System.out.println("签名后: "+Arrays.toString(cPacket.getRawData()));
System.out.println("签名后len: "+cPacket.getRawData().length);
// 打印带签名的CPacket的标识区
byte[] oldIdentifierArea=extractIdentifierArea(cPacket.getRawData());
System.out.println("&标识区: "+Arrays.toString(oldIdentifierArea));
// 更新标识区
// byte[] newIdentifierArea=getNewIdentifierArea(oldIdentifierArea);
// System.out.println("新标识区:"+ Arrays.toString(newIdentifierArea));
// 提取签名参数区
byte[] sigParamsArea=extractSigParamsArea(cPacket.getRawData());
System.out.println("&签名参数区:"+ Arrays.toString(sigParamsArea));
// 制造只读区
byte[] bytes=new byte[10];
byte[] reayonlyArea=genReayonlyArea(bytes);
System.out.println("&只读区: "+Arrays.toString(reayonlyArea));
// 合并标识区和只读区
assert oldIdentifierArea != null;
// byte[] idenAndReadonly=new byte[oldIdentifierArea.length+reayonlyArea.length];
// System.arraycopy(oldIdentifierArea,0,idenAndReadonly,0,oldIdentifierArea.length);
// System.arraycopy(reayonlyArea,0,idenAndReadonly,oldIdentifierArea.length,reayonlyArea.length);
byte[] idenAndReadonly=mergeIdentityAndReayonly(oldIdentifierArea,reayonlyArea);
System.out.println("合并标识区和只读区:"+ Arrays.toString(idenAndReadonly));
// 计算签名值区的密文
byte[] signValueBytes;
try {
System.out.println("签名名称: "+KeyManagerExample.INSTANCE.getKeyChain().getCurrentIdentity().getName());
signValueBytes=KeyManagerExample.INSTANCE.getKeyChain().signBytes(idenAndReadonly);
} catch (Exception e) {
e.printStackTrace();
return;
}
System.out.println("签名值区的密文: "+ Arrays.toString(signValueBytes));
System.out.println("签名值区的密文长度: "+signValueBytes.length);
// 验签:由于每次签名的结果(长度和数值)有一定随机性,因此这里使用验签来辩证是否成功签名
try {
System.out.println("验签结果: "+KeyManagerExample.INSTANCE.getKeyChain().verifyBytes(
idenAndReadonly,signValueBytes));
} catch (Exception e) {
e.printStackTrace();
}
// 根据密文构造签名值区
byte[] sigValueArea=genSigValueArea(signValueBytes);
System.out.println("&签名值区: "+ Arrays.toString(sigValueArea));
// 构造签名区
assert sigParamsArea != null;
byte[] sigArea=genSigArea(sigParamsArea,sigValueArea);
System.out.println("签名区: "+ Arrays.toString(sigArea));
// 构造可变区
byte[] varDataArea = new byte[]{(byte)53,(byte)5,(byte)55,(byte)3,
(byte)212,(byte)1,(byte)64}; // 可变区:TTL字段,TTL为64
// 构造整个包
System.out.println(Arrays.toString(genCPacket(oldIdentifierArea, sigArea, reayonlyArea, varDataArea)));
}
/**
*
* @param identifierArea 标识区
* @param sigArea 签名区
* @param reayonlyArea 只读区
* @param varDataArea 可变区
* @return
*/
public static byte[] genCPacket(byte[] identifierArea,byte[] sigArea,
byte[] reayonlyArea,byte[] varDataArea){
VlInt packetlen=new VlInt(identifierArea.length+sigArea.length
+reayonlyArea.length+varDataArea.length);
int allLen;
try {
allLen=1+packetlen.size()+packetlen.getVlIntValue2Int();
} catch (VlIntException e) {
e.printStackTrace();
return null;
}
int startIndex=0;
byte[] cpacketBytes=new byte[allLen];
cpacketBytes[startIndex]=(byte) 5;
startIndex++;
System.arraycopy(packetlen.getVlIntBytes(),0,cpacketBytes,startIndex,packetlen.size());
startIndex+=packetlen.size();
System.arraycopy(identifierArea,0,cpacketBytes,startIndex,identifierArea.length);
startIndex+=identifierArea.length;
System.arraycopy(sigArea,0,cpacketBytes,startIndex,sigArea.length);
startIndex+=sigArea.length;
System.arraycopy(reayonlyArea,0,cpacketBytes,startIndex,reayonlyArea.length);
startIndex+=reayonlyArea.length;
System.arraycopy(varDataArea,0,cpacketBytes,startIndex,varDataArea.length);
return cpacketBytes;
}
public static byte[] genSigArea(byte[] sigParamsArea,byte[] sigValueArea){
VlInt siglen=new VlInt(sigParamsArea.length+sigValueArea.length);
int allLen=1+siglen.size()+sigParamsArea.length+sigValueArea.length;
byte[] sigArea=new byte[allLen];
sigArea[0]=(byte) 51;
System.arraycopy(siglen.getVlIntBytes(),0,sigArea,1,siglen.size());
System.arraycopy(sigParamsArea,0,sigArea,1+siglen.size(),sigParamsArea.length);
System.arraycopy(sigValueArea,0,sigArea,1+siglen.size()+sigParamsArea.length,sigValueArea.length);
return sigArea;
}
public static byte[] genSigValueArea(byte[] sigValue){
VlInt vlInt=new VlInt(sigValue.length);
int allLen=sigValue.length+vlInt.size()+1;
byte[] sigValueArea=new byte[allLen];
sigValueArea[0]=(byte) 200;
System.arraycopy(vlInt.getVlIntBytes(),0,sigValueArea,1,vlInt.size());
System.arraycopy(sigValue,0,sigValueArea,1+vlInt.size(),sigValue.length);
return sigValueArea;
}
public static byte[] mergeIdentityAndReayonly(byte[] identifierArea,byte[] readonlyArea){
// 读取标识区负载长度
VlInt identifierLen;
try {
identifierLen= TLV.readVarNumber(identifierArea,new VlInt(1));
} catch (TLVException e) {
e.printStackTrace();
return null;
}
// 读取只读区负载长度
VlInt readLen;
try {
readLen= TLV.readVarNumber(readonlyArea,new VlInt(1));
} catch (TLVException e) {
e.printStackTrace();
return null;
}
// 合并区总长度
int allLen;
try {
allLen=identifierLen.getVlIntValue2Int()+readLen.getVlIntValue2Int();
} catch (VlIntException e) {
e.printStackTrace();
return null;
}
// 拷贝到合并数组
byte[] mergeArray=new byte[allLen];
try {
System.arraycopy(identifierArea,1+identifierLen.size(),
mergeArray,0,identifierLen.getVlIntValue2Int());
System.arraycopy(readonlyArea,1+readLen.size(),
mergeArray,identifierLen.getVlIntValue2Int(),readLen.getVlIntValue2Int());
} catch (VlIntException e) {
e.printStackTrace();
return null;
}
return mergeArray;
}
/**
* 计算整个标识区的长度,并返回该标识区
* @param targetArray 带签名的CPacket做编码得到的byte[]
* @return
*/
public static byte[] extractIdentifierArea(byte[] targetArray){
int identifierEndPos=testPrivate.findThePos(targetArray)+10;
// 读取整个CPacket的总长度
VlInt allLen;
try {
allLen= TLV.readVarNumber(targetArray,new VlInt(1));
} catch (TLVException e) {
e.printStackTrace();
return null;
}
System.out.println("CPacket-负载长度: "+allLen);
// 计算标识区的长度
int identifierLen=identifierEndPos-1-allLen.size();
// 提取标识区
byte[] identifierArea=new byte[identifierLen];
System.arraycopy(targetArray,1+allLen.size(),identifierArea,0,identifierLen);
return identifierArea;
}
/**
* 提取签名参数区
* @param targetArray
* @return
*/
public static byte[] extractSigParamsArea(byte[] targetArray){
int identifierEndPos=testPrivate.findThePos(targetArray)+10;
// 读取整个签名区的总长度
VlInt sigAreaLen;
try {
sigAreaLen = TLV.readVarNumber(targetArray,new VlInt(identifierEndPos+1));
} catch (TLVException e) {
e.printStackTrace();
return null;
}
System.out.println("签名区-负载长度: "+sigAreaLen);
// 计算签名参数区的长度
VlInt sigParamsAreaLen;
try {
sigParamsAreaLen=TLV.readVarNumber(targetArray,new VlInt(identifierEndPos+1
+sigAreaLen.size()+1));
} catch (TLVException e) {
e.printStackTrace();
return null;
}
System.out.println("签名参数区-负载长度: "+sigParamsAreaLen);
// 提取签名参数区
int sigParamsAllLen;
byte[] sigParamsArea;
try {
sigParamsAllLen=sigParamsAreaLen.getVlIntValue2Int()+1+sigParamsAreaLen.size();
sigParamsArea = new byte[sigParamsAllLen];
} catch (VlIntException e) {
e.printStackTrace();
return null;
}
System.out.println("签名参数区-总长度:"+sigParamsAllLen);
System.arraycopy(targetArray,identifierEndPos+1+sigAreaLen.size(),
sigParamsArea,0,sigParamsAllLen);
return sigParamsArea;
}
/**
* 产生一个新的标识区:替换最后10个字节为随机的byte[]
* @return
*/
public static byte[] getNewIdentifierArea(byte[] oldIdentifierArray){
System.arraycopy(testPrivate.getFixLenthString(10).getBytes(StandardCharsets.UTF_8),
0,oldIdentifierArray,oldIdentifierArray.length-10,10);
return oldIdentifierArray;
}
public static byte[] genReayonlyArea(byte[] buf){
VlInt payloadLen=new VlInt(buf.length);
VlInt readonlyLen=new VlInt(buf.length+payloadLen.size()+1);
int allLen=buf.length+payloadLen.size()+1+readonlyLen.size()+1;
byte[] readonlyArea=new byte[allLen];
readonlyArea[0]=(byte)52;
System.arraycopy(readonlyLen.getVlIntBytes(),0,readonlyArea,1,readonlyLen.size());
readonlyArea[1+readonlyLen.size()]=(byte)204;
System.arraycopy(payloadLen.getVlIntBytes(),0,readonlyArea,
1+readonlyLen.size()+1,payloadLen.size());
System.arraycopy(buf,0,readonlyArea,
1+readonlyLen.size()+1+payloadLen.size(),buf.length);
return readonlyArea;
}
}