Merge branch 'master' of gitee.com:willfree/min-dev-java

This commit is contained in:
free will committed 2021-03-05 11:46:11 +08:00
commit 84ae7d1443
18 files changed
+750 -1

No files matched your search

+192
View File
@@ -0,0 +1,192 @@
package encoding;
import util.ByteHelper;
import java.util.LinkedList;
import java.util.List;
/*
* @Author: Wang Feng
* @Description:
* @Version: 1.0.0
* @Date: 14:19 2021/3/2
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
// TLV 组件容器
class ElementContainer{
private List<Block> ElementContainer;
public ElementContainer(){
ElementContainer= new LinkedList<>();
}
public int length(){
return ElementContainer.size();
}
}
public class Block {
private VlInt tlvType; // TLV-TYPE
private VlInt length; // TLV-LENGTH
private byte[] value; // TLV-VALUE
private ElementContainer elements; // TLV-sub-elements
private byte[] raw; // TLV编码后的字节数组
/**
* 从一个包含TLV的字节数组中构造一个 Block 对象
* @param buffer
* @param verifyLength 是否要验证TLV的长度是否匹配,如果true,
* 则会对比解析到的 TLV-LENGTH 与 TLV-VALUE的实际长度是否匹配
* @return
*/
public Block createBlockByBuffer(byte[] buffer,boolean verifyLength){
if(buffer.length==0){
return null;
}
// 读取type
VlInt tlvType=TLV.readType(buffer,new VlInt(0));
if(tlvType==null){
return null;
}
// 读取length
VlInt tlvLength=TLV.readVarNumber(buffer,new VlInt(tlvType.SizeOfVarNumber()));
if(tlvLength==null){
return null;
}
return createBlockByTypeLengthBuffer(tlvType,tlvLength,
ByteHelper.getLenBytes(buffer,new VlInt(tlvType.SizeOfVarNumber()+tlvLength.SizeOfVarNumber()),
buffer.length-(tlvType.SizeOfVarNumber()+tlvLength.SizeOfVarNumber())),verifyLength);
}
/**
* 传入 T、L、V 构造一个 TLV Block
* @param tlvType
* @param tlvLength
* @param buffer
* @param verifyLength
* @return
*/
public Block createBlockByTypeLengthBuffer(VlInt tlvType,VlInt tlvLength,byte[] buffer,boolean verifyLength){
return new Block(tlvType,tlvLength,buffer,verifyLength);
}
/**
* 构造函数
* @param tlvType
* @param tlvLength
* @param buffer
* @param verifyLength
*/
public Block(VlInt tlvType,VlInt tlvLength,byte[] buffer,boolean verifyLength){
this.tlvType=tlvType;
this.length=tlvLength;
// 检查长度是否正确
if(verifyLength && (!this.length.isEqual(buffer.length))){
//todo: 抛出异常
}
// todo;设置 Raw
// todo 设置Value
}
public VlInt getTlvType() {
return tlvType;
}
public void setTlvType(VlInt tlvType) {
this.tlvType = tlvType;
}
public VlInt getLength() {
return length;
}
public void setLength(VlInt length) {
this.length = length;
}
public byte[] getValue() {
return value;
}
public void setValue(byte[] value) {
this.value = value;
}
public byte[] getRaw() {
return raw;
}
/**
* 整个TLV编码后的大小,包含T和L
* @return
*/
public SizeT Size(){
if(!this.isValid()){
return null;
}
return new SizeT(this.tlvType.SizeOfVarNumber()+this.length.SizeOfVarNumber()+this.value.length);
}
/**
* 判断当前的 Block 对象是否含有 value
* @return
*/
public boolean hasValue(){
return this.value.length!=0;
}
/**
* 判断当前的 Block 对象是否含有 raw数组
* @return
*/
public boolean hasRaw(){
return this.raw.length!=0;
}
// ************** Sub-Elements **************
/**
* 判断当前 TLV Block 是否包含子 TLV
* 1. 每次通过 CreateBlockBy* 系列工厂方法构造出Block之后,需要手动调用 ParseSubElements 方法,
* 才会去解析一级子TLV
* @return
*/
public boolean hasSubElement(){
return this.elements.length()!=0;
}
/**
* 获取所有的一级子TLV Block
* * 1. 每次通过 CreateBlockBy* 系列工厂方法构造出Block之后,需要手动调用 ParseSubElements 方法,
* * 才会去解析一级子TLV
* @return
*/
public ElementContainer getSubElements(){
return this.elements;
}
/**
* 从 value 字节数组中解析出所有的一级子 TLV Block
* 1. 这要求这个TLV确实存在嵌套的子TLV,或者为空;
* 2. 如果TLV的value不为空,且不存在嵌套的子TLV,则会抛出错误
* @return
*/
// public boolean parseSubElements(){
//
// }
/**
* 判断是否有效
* @return
*/
public boolean isValid(){
return true;
}
}
+181
View File
@@ -0,0 +1,181 @@
package encoding;
import java.math.BigInteger;
import static java.lang.Math.pow;
/*
* @Author: Wang Feng
* @Description:变长无符号整型,用于表示TLV中的T和L
* @Version: 1.0.0
* @Date: 18:13 2021/3/1
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public class SizeT {
// 实际传输的数据
private byte[] VlIntBytes;
// 变长整数表示的真实数值
private BigInteger VlIntValue;
/**
* 测量一个变长整型实际用几个字节表示
* @return
*/
public int SizeOfVarNumber(){
return SizeOfVarNumber(this.VlIntValue);
}
private static int SizeOfVarNumber(BigInteger bigInteger){
if(bigInteger.compareTo(BigInteger.valueOf(Long.parseLong("241"))) < 0){
return 1;
}else if(bigInteger.compareTo(BigInteger.valueOf(
new Double(pow(2, 16)).longValue())) < 0){
return 3;
}else if(bigInteger.compareTo(BigInteger.valueOf(
new Double(pow(2, 32)).longValue())) < 0){
return 5;
}else{ //MIN1.0中,VlInt的size最大为9
return 9;
}
}
//todo:判断bytes是否是一个合法的变长非负整型
//todo:判断biginteger是否合法
public SizeT(byte[] bytes){
this.VlIntBytes=bytes;
this.VlIntValue=vlintBytes2bigInteger(bytes);
}
public SizeT(BigInteger bigInteger){
this.VlIntValue=bigInteger;
this.VlIntBytes=bigInteger2vlintBytes(bigInteger);
}
// 传入一个变长无符号字节数组byte[],将它解析成一个VlInt
public SizeT createVlInt(byte[] bytes){
return new SizeT(bytes);
}
// 传入一个BigInteger,将它解析成一个VlInt
public SizeT createVlIntByBigInteger(BigInteger bigInteger){
return new SizeT(bigInteger);
}
// todo:传入一个int,将它解析成一个VlInt
public SizeT(int i){
this.VlIntValue=new BigInteger(String.valueOf(i));
this.VlIntBytes=bigInteger2vlintBytes(this.VlIntValue);
}
// todo:传入一个long,将它解析成一个VlInt
// 将vlint转为一个int输出:需要判断size是不是小于4(1 or 3)
public Integer getVlIntValue2Int(){
if(this.SizeOfVarNumber()<4){
return VlIntValue.intValue();
}
return null;
}
// 将vlint转为一个long输出:需要判断size是不是小于8(5)
public Long getVlIntValue2Long(){
if(this.SizeOfVarNumber()<8){
return VlIntValue.longValue();
}
return null;
}
// 将vlint转为一个biginteger输出:需要判断size是不是等于9(9)
public BigInteger getVlIntValue(){
if(this.SizeOfVarNumber()>=9){
return VlIntValue;
}
return null;
}
// 判断vlint是否与某个int值相等
public boolean isEqual(Integer vlint){
return isEqual(vlint.intValue());
}
public boolean isEqual(int i){
if(this.VlIntValue.compareTo(new BigInteger(String.valueOf(i)))==0){
return true;
}
return false;
}
public boolean isEqual(SizeT vlInt){
if(this.VlIntValue.compareTo(vlInt.VlIntValue)==0){
return true;
}
return false;
}
// todo: 判断vlint是否与某个long值相等
/**
* 判断与另一个VlInt的数值孰大孰小
* @param vlInt
* @return
*/
public int compareTo(SizeT vlInt){
return this.VlIntValue.compareTo(vlInt.VlIntValue);
}
public int compareTo(int i){
BigInteger bigInteger=new BigInteger(String.valueOf(i));
return this.VlIntValue.compareTo(bigInteger);
}
/**
* 减去另一个VlInt
* todo:暂没考虑两者差值越界int最大值
* @param vlInt
* @return
*/
public int subtract(SizeT vlInt){
return this.VlIntValue.subtract(vlInt.VlIntValue).intValue();
}
// 将BigInteger转为byte[按照变长无符号整数方式转]
private byte[] bigInteger2vlintBytes(BigInteger bigInteger){
byte[] vlintbytes;
if(SizeOfVarNumber(bigInteger)==1){
vlintbytes=new byte[1];
//todo
}else if(SizeOfVarNumber(bigInteger)==3){
vlintbytes=new byte[3];
//todo
}else if(SizeOfVarNumber(bigInteger)==5){
vlintbytes=new byte[5];
//todo
}else{
vlintbytes=new byte[9];
//todo
}
return vlintbytes;
}
// 将变长无符号整数数组转为BigInteger
private BigInteger vlintBytes2bigInteger(byte[] vlIntBytes){
BigInteger vlintValue=null;
if(vlIntBytes.length==1){
//todo
}else if(vlIntBytes.length==3){
//todo
}else if(vlIntBytes.length==5){
//todo
}else if(vlIntBytes.length==9){
//todo
}else{
return null;
}
return vlintValue;
}
// 测试
public static void main(String[] args){
BigInteger bigInteger=new BigInteger("3");
SizeT vlInt=new SizeT(bigInteger);
System.out.println(vlInt.isEqual(2));
}
}
+155
View File
@@ -0,0 +1,155 @@
package encoding;
import static util.ByteHelper.*;
/*
* @Author: Wang Feng
* @Description:
* @Version: 1.0.0
* @Date: 17:54 2021/3/1
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public class TLV {
////// 一级:网络分组级别TLV号分配(0 ~ 49)
public static final int TlvInvalid = 0; // 无效包
public static final int TlvPacketMINCommon = 5; // 通用MIN包
public static final int TlvPacketMINManagement = 6; // MIN管理包
public static final int TlvPacketMINIP = 7; // MIN支持IP包
////// 二级:网络包分区TLV号分配 (50 ~ 99)
public static final int TlvIdentifierField = 50; // 目的标识区
public static final int TlvSignatureField = 51; // 数字签名区
public static final int TlvReadOnlyField = 52; // 只读数据区
public static final int TlvMutableField = 53; // 可变数据区
public static final int TlvMutableProtectField = 54; // 可变数据区中的保护区
public static final int TlvMutableDangerousField = 55; // 可变数据区中的非受保护区
////// 组件 (100 -> 500)
// 标识分配
public static final int TlvIdentifierComponent = 100; // 标识名称组件
public static final int TlvIdentifier = 101; // 标识
public static final int TlvIdentifierCommon = 102; // 身份标识
public static final int TlvIdentifierContentInterest = 103; // 内容兴趣标识
public static final int TlvIdentifierContentData = 104; // 内容数据标识
// 数字签名
public static final int TlvSignatureValue = 200; // 签名值
public static final int TlvSignatureInfo = 201; // 签名参数
public static final int TlvSignatureType = 202; // 签名类型
public static final int TlvKeyLocator = 203; // 指示证书或公钥的位置
public static final int TlvPayload = 204; // 网络包负载
public static final int TlvCanBePrefix = 205; // 是否可以被较长的数据包前缀匹配
public static final int TlvMustBeRefresh = 206; // 是否强制只拉取新鲜的数据
public static final int TlvInterestLifeTime = 207; // 兴趣包生存期
public static final int TlvNonce = 208; // 随机数
public static final int TlvHopLimit = 209; // 跳数限制
public static final int TlvFreshnessPeriod = 210; // 数据包新鲜时间
public static final int TlvCongestionMark = 211; // 拥塞标记
public static final int TlvTTL = 212; // Time to live
public static final int TlvNackHeader = 213; // Nack header
// 管理通信协议
public static final int TlvSliceNumber = 211; // 分片数量
public static final int TlvSliceSize = 212; // 分片大小
public static final int TlvTlvLogicFaceId = 213; // 逻辑接口id
public static final int TlvRemoteAddr = 214; // 源端地址
public static final int TlvLocalAddr = 215; // 本地地址
public static final int TlvMtu = 216; // 最大传输单元
public static final int TlvRet = 217; // bool类型,成功或失败
public static final int TlvOrigin = 218; //
public static final int TlvCost = 219; // 链路开销
public static final int TlvExpires = 220; // LogicFace超时时间,-1为不超时(never)
// 目前已分配的最大的Tlv值,第一轮分配的最大值为500,超过该值则断定为不合法
// TODO: 目前TLV值的分配,第一轮分配都在500以内,如果以后分配更高值时,需要修改此处的限制
public static final int MaxTlvNum = 500;
/**
* 从字节数组中读出一个变长整型
* @param buffer
* @param start
* @return
*/
public static VlInt readVarNumber(byte[] buffer,VlInt start){
VlInt length=new VlInt(buffer.length);
if(start.compareTo(length)>=0){
return null;
}
int firstbyte=uint8ToInt(getFirstByte(buffer,start));
if(firstbyte<241){
return new VlInt(firstbyte);
}else if(firstbyte==241){
if(length.subtract(start)<3){
return null;
}
return new VlInt(getLenBytes(buffer,start,3));
}else if(firstbyte==242){
if(length.subtract(start)<5){
return null;
}
return new VlInt(getLenBytes(buffer,start,5));
}else if(firstbyte==243){
if(length.subtract(start)<9){
return null;
}
return new VlInt(getLenBytes(buffer,start,9));
}else{ //MIN1.0中算越界
return null;
}
}
/**
* 从字节数组的指定位置中读取一个变长的整型作为 TLV Type
* @param buffer
* @param start
* @return
*/
public static VlInt readType(byte[] buffer,VlInt start){
VlInt tlvType=readVarNumber(buffer,start);
if(tlvType==null||tlvType.isEqual(0)||tlvType.compareTo(MaxTlvNum)>0){
return null;
}
return tlvType;
}
// todo:从字节数组的指定位置中读取一个非负整型
/**
* 检查某个type值是否是指定的 TLV-TYPE
* @param current
* @param target
* @return
*/
public static boolean expectType(VlInt current,VlInt target){
if(current.isEqual(target)){
return true;
}
return false;
}
/**
* 根据 TLV 分配规则,判断某个tlvType是否是合规的标识类型
* TODO: 目前TLV的分配是500为一轮,如果标识范围扩展了,本方法需要对应修改
* @param tlvType
* @return
*/
public static boolean isValidIdentifierType(VlInt tlvType){
return tlvType.compareTo(102)>=0 && tlvType.compareTo(199)<=0;
}
/**
* 根据 TLV 分配规则,判断某个tlvType是否是合规的包类型
* TODO: 目前TLV的分配是500为一轮,如果标识范围扩展了,本方法需要对应修改
* @param tlvType
* @return
*/
public static boolean isValidPacketType(VlInt tlvType){
return tlvType.compareTo(0)>0 && tlvType.compareTo(50)<0;
}
//todo: 错误处理
}
+236
View File
@@ -0,0 +1,236 @@
package encoding;
import util.ByteHelper;
import java.math.BigInteger;
import static java.lang.Math.pow;
/*
* @Author: Wang Feng
* @Description:变长无符号整型,用于表示TLV中的T和L
* @Version: 1.0.0
* @Date: 18:13 2021/3/1
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public class VlInt {
// 实际传输的数据
private byte[] VlIntBytes;
// 变长整数表示的真实数值
private BigInteger VlIntValue;
// 一些int常量
// @Description:
// 1. x < 240 => 1字节表示 => 230
// 2. 241 =< x < uint16::Max => 第一个字节为241,后面连着2字节表示实际数值,总共用3个字节表示 => 246
// 3. uint16::Max =< x < uint32::Max => 第一个字节为242,后面连着4字节表示实际数值,总共用5个字节表示
// 4. int32::Max =< x < int64::Max => 第一个字节为243,后面连着8字节表示实际数值,总共用9个字节表示
// 5. 后续还留有12个字节可以进行指数级扩展,目前留空
public static final int VlIntExtend2=241;
public static final int VlIntExtend4=242;
public static final int VlIntExtend8=243;
/**
* 测量一个变长整型实际用几个字节表示
* @return
*/
public int SizeOfVarNumber(){
return SizeOfVarNumber(this.VlIntValue);
}
private static int SizeOfVarNumber(BigInteger bigInteger){
if(bigInteger.compareTo(BigInteger.valueOf(Long.parseLong("241"))) < 0){
return 1;
}else if(bigInteger.compareTo(BigInteger.valueOf(
new Double(pow(2, 16)).longValue())) < 0){
return 3;
}else if(bigInteger.compareTo(BigInteger.valueOf(
new Double(pow(2, 32)).longValue())) < 0){
return 5;
}else{ //MIN1.0中,VlInt的size最大为9
return 9;
}
}
//todo:判断bytes是否是一个合法的变长非负整型
//todo:判断biginteger是否合法
public VlInt(byte[] bytes){
this.VlIntBytes=bytes;
this.VlIntValue=vlintBytes2bigInteger(bytes);
}
public VlInt(BigInteger bigInteger){
this.VlIntValue=bigInteger;
this.VlIntBytes=bigInteger2vlintBytes(bigInteger);
}
public VlInt(int i){
this.VlIntValue=BigInteger.valueOf(i);
this.VlIntBytes=bigInteger2vlintBytes(this.VlIntValue);
}
public VlInt(long l){
this.VlIntValue=BigInteger.valueOf(l);
this.VlIntBytes=bigInteger2vlintBytes(this.VlIntValue);
}
// 传入一个变长无符号字节数组byte[],将它解析成一个VlInt
public VlInt createVlInt(byte[] bytes){
return new VlInt(bytes);
}
// 传入一个BigInteger,将它解析成一个VlInt
public VlInt createVlIntByBigInteger(BigInteger bigInteger){
return new VlInt(bigInteger);
}
/**
* 将vlint转为一个int输出:需要判断size是不是小于4(1 or 3)
* @return
*/
public int getVlIntValue2Int(){
if(this.SizeOfVarNumber()<4){
return VlIntValue.intValue();
}
return Integer.parseInt(null);
}
/**
* 将vlint转为一个long输出:需要判断size是不是小于8(5)
* @return
*/
public long getVlIntValue2Long(){
if(this.SizeOfVarNumber()<8){
return VlIntValue.longValue();
}
return Long.parseLong(null);
}
/**
* 将vlint转为一个biginteger输出:需要判断size是不是等于9(9)
* @return
*/
public BigInteger getVlIntValue(){
if(this.SizeOfVarNumber()>=9){
return VlIntValue;
}
return null;
}
/**
* 判断vlint是否与某个值相等
* @param vlInt
* @return
*/
public boolean isEqual(VlInt vlInt){
if(this.VlIntValue.compareTo(vlInt.VlIntValue)==0){
return true;
}
return false;
}
public boolean isEqual(int i){
if(this.VlIntValue.compareTo(BigInteger.valueOf(i))==0){
return true;
}
return false;
}
public boolean isEqual(long l){
if(this.VlIntValue.compareTo(BigInteger.valueOf(l))==0){
return true;
}
return false;
}
/**
* 判断与另一个VlInt的数值孰大孰小
* @param vlInt
* @return
*/
public int compareTo(VlInt vlInt){
return this.VlIntValue.compareTo(vlInt.VlIntValue);
}
public int compareTo(int i){
BigInteger bigInteger=BigInteger.valueOf(i);
return this.VlIntValue.compareTo(bigInteger);
}
public int compareTo(long l){
BigInteger bigInteger=BigInteger.valueOf(l);
return this.VlIntValue.compareTo(bigInteger);
}
/**
* 减去另一个VlInt
* todo:暂没考虑两者差值越界int最大值
* @param vlInt
* @return
*/
public int subtract(VlInt vlInt){
return this.VlIntValue.subtract(vlInt.VlIntValue).intValue();
}
/**
* 将BigInteger转为byte[按照变长无符号整数方式转]
* @param bigInteger
* @return
*/
private byte[] bigInteger2vlintBytes(BigInteger bigInteger){
byte[] vlintbytes;
if(SizeOfVarNumber(bigInteger)==1){
vlintbytes=new byte[1];
vlintbytes[0]= ByteHelper.uint8ToByte(bigInteger.intValue());
}else if(SizeOfVarNumber(bigInteger)==3){
vlintbytes=new byte[3];
vlintbytes[0]=ByteHelper.uint8ToByte(VlIntExtend2);
System.arraycopy(ByteHelper.uint16ToByteArray(bigInteger.intValue()),0,vlintbytes,1,2);
}else if(SizeOfVarNumber(bigInteger)==5){
vlintbytes=new byte[5];
vlintbytes[0]=ByteHelper.uint8ToByte(VlIntExtend4);
System.arraycopy(ByteHelper.uint32ToByteArray(bigInteger.longValue()),0,vlintbytes,1,4);
}else{
vlintbytes=new byte[9];
vlintbytes[0]=ByteHelper.uint8ToByte(VlIntExtend8);
System.arraycopy(ByteHelper.uint64ToByteArray(bigInteger.longValue()),0,vlintbytes,1,8);
}
return vlintbytes;
}
/**
* 将变长无符号整数数组转为BigInteger
* @param vlIntBytes
* @return
*/
private BigInteger vlintBytes2bigInteger(byte[] vlIntBytes){
BigInteger vlintValue;
if(vlIntBytes.length==1){
long value=ByteHelper.uint8ToLong(vlIntBytes[0]);
vlintValue=BigInteger.valueOf(value);
}else if(vlIntBytes.length==3){
byte[] valueByte=new byte[2];
System.arraycopy(vlIntBytes,1,valueByte,0,valueByte.length);
long value=ByteHelper.uint16ToLong(valueByte);
vlintValue=BigInteger.valueOf(value);
}else if(vlIntBytes.length==5){
byte[] valueByte=new byte[4];
System.arraycopy(vlIntBytes,1,valueByte,0,valueByte.length);
long value=ByteHelper.uint32ToLong(valueByte);
vlintValue=BigInteger.valueOf(value);
}else if(vlIntBytes.length==9){
byte[] valueByte=new byte[8];
System.arraycopy(vlIntBytes,1,valueByte,0,valueByte.length);
long value=ByteHelper.uint64ToLong(valueByte);
vlintValue=BigInteger.valueOf(value);
}else{
return null;
}
return vlintValue;
}
// 测试
public static void main(String[] args){
BigInteger bigInteger=new BigInteger("3");
VlInt vlInt=new VlInt(bigInteger);
System.out.println(vlInt.isEqual(2));
}
}
+39
View File
@@ -0,0 +1,39 @@
package encoding;
import static java.lang.Math.pow;
/*
* @Author: Wang Feng
* @Description:变长无符号整型,用于表示TLV中的T和L
* @Version: 1.0.0
* @Date: 22:58 2021/3/1
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public class VlInt_V1 {
// 实际传输的数据
private byte[] VlIntByte;
// 变长整数表示的真实数值:
// MIN1.0最大为(2^64-1),此处用long表示,则可能发生越界
private long VlIntValue;
// 传入一个变长无符号字节数组byte[],将它解析成一个VlInt
// 传入一个int,将它解析成一个VlInt
// 将vlint转为一个int输出
/**
* 测量一个变长整型实际用几个字节表示
* @return int
*/
public int SizeOfVarNumber(){
if(VlIntValue<241){
return 1;
}else if(VlIntValue<new Double(pow(2,16))){
return 3;
}else{
return 5;
}
}
}
@@ -0,0 +1,18 @@
package minsecurity;
import org.bouncycastle.crypto.CryptoException;
import org.bouncycastle.crypto.InvalidCipherTextException;
/*
* @Author: hongyu guo
* @Description: 所有对称加密方法必须实现的基本方法
* @Version: 1.0.0
* @Date: 17:28 2021/03/03
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public interface PrivateKeyInterface {
public byte[] getBytes();
public boolean setBytes(byte[] bytes);
public byte[] decrypt(byte[] content) throws InvalidCipherTextException;
public byte[] sign(byte[] content) throws CryptoException;
}
@@ -0,0 +1,17 @@
package minsecurity;
/*
* @Author: hongyu guo
* @Description: 所有对称加密方法必须实现的基本方法
* @Version: 1.0.0
* @Date: 17:06 2021/03/03
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
import org.bouncycastle.crypto.InvalidCipherTextException;
public interface PublicKeyInterface {
public byte[] getBytes();
public boolean setBytes(byte[] bytes);
public byte[] encrypt(byte[] content) throws InvalidCipherTextException;
public boolean verify(byte[] content, byte[] digest);
}
@@ -0,0 +1,49 @@
package minsecurity.crypto.sm2;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.math.ec.custom.gm.SM2P256V1Curve;
import org.slf4j.LoggerFactory;
import java.math.BigInteger;
import java.security.SecureRandom;
/*
* @Author: hongyu guo
* @Description: SM2推荐曲线参数
* @Version: 1.0.0
* @Date: 18:48 2021/03/03
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public class Sm2Base {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Sm2Base.class);
public static final SM2P256V1Curve CURVE = new SM2P256V1Curve();
public final static BigInteger SM2_ECC_P = CURVE.getQ();
public final static BigInteger SM2_ECC_A = CURVE.getA().toBigInteger();
public final static BigInteger SM2_ECC_B = CURVE.getB().toBigInteger();
public final static BigInteger SM2_ECC_N = CURVE.getOrder();
public final static BigInteger SM2_ECC_H = CURVE.getCofactor();
public final static BigInteger SM2_ECC_GX = new BigInteger(
"32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", 16);
public final static BigInteger SM2_ECC_GY = new BigInteger(
"BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0", 16);
public static final ECPoint G_POINT = CURVE.createPoint(SM2_ECC_GX, SM2_ECC_GY);
public static final ECDomainParameters DOMAIN_PARAMS = new ECDomainParameters(CURVE, G_POINT,
SM2_ECC_N, SM2_ECC_H);
public static AsymmetricCipherKeyPair generateKeyPairParameter(){
SecureRandom random = new SecureRandom();
ECKeyGenerationParameters keyGenerationParams = new ECKeyGenerationParameters(DOMAIN_PARAMS,
random);
ECKeyPairGenerator keyGen = new ECKeyPairGenerator();
keyGen.init(keyGenerationParams);
AsymmetricCipherKeyPair keyPair = keyGen.generateKeyPair();
ECPrivateKeyParameters privateKeyParameters = (ECPrivateKeyParameters) keyPair.getPrivate();
logger.debug("priv D: bitlen = {}, d.len = {}",privateKeyParameters.getD().bitLength(),privateKeyParameters.getD().toByteArray().length);
return keyPair;
}
}
@@ -0,0 +1,14 @@
package minsecurity.crypto.sm2;
/*
* @Author: hongyu guo
* @Description: sm2的自定义异常
* @Version: 1.0.0
* @Date: 19:00 2021/03/03
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public class Sm2Exception extends java.lang.Exception {
public Sm2Exception(String msg){
super(msg);
}
}
@@ -0,0 +1,83 @@
package minsecurity.crypto.sm2;
import minsecurity.PrivateKeyInterface;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.CryptoException;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ParametersWithID;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.crypto.signers.SM2Signer;
import java.math.BigInteger;
import java.security.SecureRandom;
/*
* @Author: hongyu guo
* @Description: 国密sm2 非对称加密私钥
* @Version: 1.0.0
* @Date: 19:40 2021/03/03
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public class Sm2PrivateKey implements PrivateKeyInterface {
Sm2PrivateKey(){}
Sm2PrivateKey(byte[] d) {
if(d.length == 32 || d.length == 33)
privateKey = new ECPrivateKeyParameters(new BigInteger(d), Sm2Base.DOMAIN_PARAMS);
else {
try {
throw new Sm2Exception("SM2私钥中,参数d长度应为32/33");
} catch (Sm2Exception e) {
e.printStackTrace();
}
}
}
Sm2PrivateKey(byte[] d, ECDomainParameters parameters){
if(d.length == 32 || d.length == 33)
privateKey = new ECPrivateKeyParameters(new BigInteger(d), parameters);
else {
try {
throw new Sm2Exception("SM2私钥中,参数d长度应为32/33");
} catch (Sm2Exception e) {
e.printStackTrace();
}
}
}
@Override
public byte[] getBytes() {
return privateKey.getD().toByteArray();
}
@Override
public boolean setBytes(byte[] d) {
if(d.length != 32 && d.length != 33)
return false;
privateKey = new ECPrivateKeyParameters(new BigInteger(d), Sm2Base.DOMAIN_PARAMS);
return true;
}
@Override
public byte[] decrypt(byte[] cipher) throws InvalidCipherTextException {
SM2Engine engine = new SM2Engine(SM2Engine.Mode.C1C2C3);
engine.init(false, privateKey);
return engine.processBlock(cipher, 0, cipher.length);
}
@Override
public byte[] sign(byte[] content) throws CryptoException {
SM2Signer signer = new SM2Signer();
CipherParameters param = null;
ParametersWithRandom pwr = new ParametersWithRandom(privateKey, new SecureRandom());
param = pwr;
signer.init(true, param);
signer.update(content, 0, content.length);
return signer.generateSignature();
}
private ECPrivateKeyParameters privateKey;
}
@@ -0,0 +1,114 @@
package minsecurity.crypto.sm2;
import minsecurity.PublicKeyInterface;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.crypto.signers.SM2Signer;
import org.bouncycastle.math.ec.ECCurve;
import java.nio.ByteBuffer;
import java.security.SecureRandom;
/*
* @Author: hongyu guo
* @Description: 国密sm2 非对称加密公钥
* @Version: 1.0.0
* @Date: 17:32 2021/03/03
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public class Sm2PublicKey implements PublicKeyInterface {
Sm2PublicKey(){}
public Sm2PublicKey(byte[] xBytes, byte[] yBytes, ECCurve curve, ECDomainParameters domainParameters){
publicKey = createPublicKey(xBytes,yBytes,curve,domainParameters);
}
public Sm2PublicKey(byte[] xBytes, byte[] yBytes){
this(xBytes,yBytes, Sm2Base.CURVE, Sm2Base.DOMAIN_PARAMS);
}
@Override
public byte[] getBytes() {
if(publicKey != null)
return publicKey.getQ().getEncoded(false); //不压缩
return new byte[0];
}
@Override
public boolean setBytes(byte[] bytes) {
if(bytes.length != 65)
return false;
ByteBuffer encoded = ByteBuffer.wrap(bytes);
byte[] x = new byte[32];
byte[] y = new byte[32];
encoded.position(1);
encoded.get(x,0,32);
encoded.get(y,0,32);
publicKey = createPublicKey(x,y);
return true;
}
@Override
public byte[] encrypt(byte[] content) throws InvalidCipherTextException {
SM2Engine engine = new SM2Engine(SM2Engine.Mode.C1C2C3);
ParametersWithRandom pwr = new ParametersWithRandom(publicKey, new SecureRandom());
engine.init(true, pwr);
return engine.processBlock(content, 0, content.length);
}
@Override
public boolean verify(byte[] content, byte[] digest) {
SM2Signer signer = new SM2Signer();
CipherParameters param = publicKey;
signer.init(false, param);
signer.update(content, 0, content.length);
return signer.verifySignature(digest);
}
////////////////////////////////////////////// private start //////////////////////////////////////////////
private static ECPublicKeyParameters createPublicKey(
byte[] xBytes, byte[] yBytes, ECCurve curve, ECDomainParameters domainParameters){
final byte uncompressedFlag = 0x04;
int curveLength = getCurveLength(domainParameters);
xBytes = fixToCurveLengthBytes(curveLength, xBytes);
yBytes = fixToCurveLengthBytes(curveLength, yBytes);
byte[] encodedPubKey = new byte[1 + xBytes.length + yBytes.length];
encodedPubKey[0] = uncompressedFlag;
System.arraycopy(xBytes, 0, encodedPubKey, 1, xBytes.length);
System.arraycopy(yBytes, 0, encodedPubKey, 1 + xBytes.length, yBytes.length);
return new ECPublicKeyParameters(curve.decodePoint(encodedPubKey), domainParameters);
}
private static ECPublicKeyParameters createPublicKey(byte[] xBytes, byte[] yBytes){
return createPublicKey(xBytes,yBytes,Sm2Base.CURVE,Sm2Base.DOMAIN_PARAMS);
}
private static int getCurveLength(ECDomainParameters domainParams) {
return (domainParams.getCurve().getFieldSize() + 7) / 8;
}
private static byte[] fixToCurveLengthBytes(int curveLength, byte[] src) {
if (src.length == curveLength) {
return src;
}
byte[] result = new byte[curveLength];
if (src.length > curveLength) {
System.arraycopy(src, src.length - result.length, result, 0, result.length);
} else {
System.arraycopy(src, 0, result, result.length - src.length, src.length);
}
return result;
}
////////////////////////////////////////////// private end //////////////////////////////////////////////
ECPublicKeyParameters publicKey;
}
+271
View File
@@ -0,0 +1,271 @@
package util;
import encoding.VlInt;
/*
* @Author: Wang Feng
* @Description:常用的数据类型转换。转无符号byte是重点
* @Version: 1.0.0
* @Date: 15:40 2021/3/2
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public class ByteHelper {
/**
* 从byte[]数组指定开始位置获取第一个字节
* todo: start位置可能是大于int类型的数值
* @param buffer
* @param start
* @return
*/
public static byte getFirstByte(byte[] buffer, VlInt start){
int startInt=start.getVlIntValue2Int();
byte[] firstbyte=new byte[1];
System.arraycopy(buffer,startInt,firstbyte,0,firstbyte.length);
return firstbyte[0];
}
/**
* 从byte[]数组指定开始位置获取长度为len的字节数组
* todo: start位置可能是大于int类型的数值
* @param buffer
* @param start
* @return
*/
public static byte[] getLenBytes(byte[] buffer, VlInt start,VlInt len){
int startInt=start.getVlIntValue2Int();
int lenInt=len.getVlIntValue2Int();
byte[] lenbytes=new byte[1];
System.arraycopy(buffer,startInt,lenbytes,0,lenInt);
return lenbytes;
}
public static byte[] getLenBytes(byte[] buffer, VlInt start,int len){
int startInt=start.getVlIntValue2Int();
byte[] lenbytes=new byte[1];
System.arraycopy(buffer,startInt,lenbytes,0,len);
return lenbytes;
}
/**
* 无符号int转byte[]
* @param i_int
* @return
*/
private static byte[] intToByteArray(int i_int) {
byte[] result = new byte[4];
//由高位到低位
for(int i=0;i<4;i++) {
int offset=(result.length-i-1)*8;
result[i] = (byte) ((i_int >>>offset) & 0xff);
}
return result;
}
/**
* 无符号byte[]转int
* @param bytes
* @return
*/
private static int byteArrayToInt(byte[] bytes) {
if(bytes.length!=4){
return Integer.parseInt(null);
}
int value= 0;
//由高位到低位
for (int i = 0; i < 4; i++) {
int offset= (bytes.length - 1 - i) * 8;
value +=(bytes[i] & 0x000000ff) << offset; //往高位游
}
return value;
}
/**
* 无符号long转byte[]
* @param l_long
* @return
*/
private static byte[] longToByteArray(long l_long) {
byte[] result = new byte[8];
for (int i = 0; i<8; i++) {
int offset = (result.length - 1 - i) * 8;
result[i] = (byte) ((l_long >>> offset) & 0xff);
}
return result;
}
/**
* 无符号byte[]转long
* @param bytes
* @return
*/
private static long byteArrayToLong(byte[] bytes) {
if(bytes.length!=8){
return Integer.parseInt(null);
}
int value= 0;
//由高位到低位
for (int i = 0; i < 8; i++) {
int offset= (bytes.length - 1 - i) * 8;
value +=(bytes[i] & 0x000000000000ff) << offset; //往高位游
}
return value;
}
/**
* 无符号字节转int
* @param b
* @return
*/
// private static int unsignedbyte2int(byte b){
// return (int) b&0xff;
// }
/**
* uint8转int
* @param uint8
* @return
*/
public static int uint8ToInt(byte uint8){
return uint8 & 0xff;
}
/**
* 一个uint8转为的int,通过本函数再次转为byte
* @param uint8
* @return
*/
public static byte uint8ToByte(int uint8){
return (byte)(uint8 & 0xff);
}
/**
* uint8转long
* @param uint8
* @return
*/
public static long uint8ToLong(byte uint8){
return uint8ToInt(uint8);
}
/**
* uint16转int
* @param uint16
* @return
*/
public static int uint16ToInt(byte[] uint16){
if(uint16.length!=2){
return Integer.parseInt(null);
}
byte[] bytes=new byte[4];
for(int i=0;i<2;i++) {
bytes[i] = 0x00;
}
System.arraycopy(uint16,0,bytes,2,uint16.length);
return byteArrayToInt(bytes);
}
/**
* 一个uint16转为的int,通过本函数再次转为byte[]
* @param uint16
* @return
*/
public static byte[] uint16ToByteArray(int uint16){
byte[] result = new byte[2];
for (int i = 0; i<2; i++) {
int offset = (result.length - 1 - i) * 8;
result[i] = (byte) ((uint16 >>> offset) & 0xff);
}
return result;
}
/**
* uint16转long
* @param uint16
* @return
*/
public static long uint16ToLong(byte[] uint16){
return uint16ToInt(uint16);
}
/**
* uint32转long
* @param uint32
* @return
*/
public static long uint32ToLong(byte[] uint32){
if(uint32.length!=4){
return Long.parseLong(null);
}
byte[] bytes=new byte[64];
for(int i=0;i<4;i++) {
bytes[i] = 0x00;
}
System.arraycopy(uint32,0,bytes,4,uint32.length);
return byteArrayToLong(bytes);
}
/**
* 一个uint32转为的long,通过本函数再次转为byte[]
* @param uint32
* @return
*/
public static byte[] uint32ToByteArray(long uint32){
byte[] result = new byte[4];
for (int i = 0; i<4; i++) {
int offset = (result.length - 1 - i) * 8;
result[i] = (byte) ((uint32 >>> offset) & 0xff);
}
return result;
}
/**
* uint64转long
* todo: 理论上可能发生越界
* @param uint64
* @return
*/
public static long uint64ToLong(byte[] uint64){
if(uint64.length!=8){
return Long.parseLong(null);
}
return byteArrayToLong(uint64);
}
/**
* 一个uint64转为的long,通过本函数再次转为byte[]
* todo: 理论上可能发生越界
* @param uint64
* @return
*/
public static byte[] uint64ToByteArray(long uint64){
byte[] result = new byte[8];
for (int i = 0; i<8; i++) {
int offset = (result.length - 1 - i) * 8;
result[i] = (byte) ((uint64 >>> offset) & 0xff);
}
return result;
}
// short整型转为byte类型的数组
// private static byte[] unsigned_short_2byte(int length) {
// byte[] targets = new byte[2];
// for (int i = 0; i < 2; i++) {
// int offset = (targets.length - 1 - i) * 8;
// targets[i] = (byte) ((length >>> offset) & 0xff);
// }
// return targets;
// }
//测试:对于uint8,应当测试1 127 128
public static void main(String[] args){
// byte[] testBytes={0x01,0x02};
// for(int i=0;i<2;i++) {
// System.out.println(testBytes[i]&0xFF);
//// System.out.println(Integer.toHexString(testBytes[i]&0xFF));
// }
byte b=-1;
System.out.println(b&0xff);
}
}