From 1fda17caea18b92eaf7cd4995a6c109c5d86bd42 Mon Sep 17 00:00:00 2001 From: yuanwei Date: Tue, 13 Aug 2024 10:33:18 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0ud=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/controller/ud/UdInfoController.java | 73 ++ .../ud/UdProducePlanController.java | 4 +- .../com/glxp/api/entity/ud/UdInfoEntity.java | 41 +- .../api/req/ud/UdInfoCheckEntityRequest.java | 23 + .../glxp/api/req/ud/UdInfoEntityRequest.java | 7 + .../api/service/sup/UserCompanyService.java | 2 + .../sup/impl/UserCompanyServiceImpl.java | 13 + .../api/service/system/CompanyService.java | 3 +- .../system/impl/CompanyServiceImpl.java | 5 + .../com/glxp/api/util/GennerOrderUtils.java | 4 +- src/main/java/com/glxp/api/util/SoftKey.java | 303 -------- .../com/glxp/api/util/sm2/ECConstants.java | 10 + .../java/com/glxp/api/util/sm2/ECCurve.java | 116 ++++ .../com/glxp/api/util/sm2/ECFieldElement.java | 120 ++++ .../java/com/glxp/api/util/sm2/ECPoint.java | 149 ++++ .../java/com/glxp/api/util/sm2/SM2Result.java | 27 + .../java/com/glxp/api/util/sm2/SM2SM3.java | 647 ++++++++++++++++++ src/main/java/com/glxp/api/util/sm2/Test.java | 96 --- 18 files changed, 1236 insertions(+), 407 deletions(-) create mode 100644 src/main/java/com/glxp/api/req/ud/UdInfoCheckEntityRequest.java create mode 100644 src/main/java/com/glxp/api/util/sm2/ECConstants.java create mode 100644 src/main/java/com/glxp/api/util/sm2/ECCurve.java create mode 100644 src/main/java/com/glxp/api/util/sm2/ECFieldElement.java create mode 100644 src/main/java/com/glxp/api/util/sm2/ECPoint.java create mode 100644 src/main/java/com/glxp/api/util/sm2/SM2Result.java create mode 100644 src/main/java/com/glxp/api/util/sm2/SM2SM3.java delete mode 100644 src/main/java/com/glxp/api/util/sm2/Test.java diff --git a/src/main/java/com/glxp/api/controller/ud/UdInfoController.java b/src/main/java/com/glxp/api/controller/ud/UdInfoController.java index 3dd6ba5..c026a3d 100644 --- a/src/main/java/com/glxp/api/controller/ud/UdInfoController.java +++ b/src/main/java/com/glxp/api/controller/ud/UdInfoController.java @@ -17,21 +17,27 @@ import com.glxp.api.entity.ud.UdInfoEntity; import com.glxp.api.entity.ud.UdProducePlanEntity; import com.glxp.api.req.anno.AnncmntDevEntityRequest; import com.glxp.api.req.system.DeleteRequest; +import com.glxp.api.req.ud.UdInfoCheckEntityRequest; import com.glxp.api.req.ud.UdInfoEntityRequest; import com.glxp.api.res.PageSimpleResponse; import com.glxp.api.service.anno.AnncmntDevService; +import com.glxp.api.service.sup.UserCompanyService; import com.glxp.api.service.ud.UdInfoService; import com.glxp.api.util.BeanCopyUtils; +import com.glxp.api.util.GennerOrderUtils; import com.glxp.api.util.StringUtils; +import com.glxp.api.util.sm2.SM2SM3; import lombok.RequiredArgsConstructor; import org.springframework.validation.BindingResult; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import springfox.documentation.annotations.ApiIgnore; +import javax.annotation.Resource; import javax.validation.Valid; import java.util.Date; import java.util.List; +import java.util.Map; /** * 用户信息 @@ -46,15 +52,26 @@ public class UdInfoController extends BaseController { private final UdInfoService udInfoService; + @Resource + GennerOrderUtils gennerOrderUtils; + + @Resource + UserCompanyService userCompanyService; + @GetMapping("/list") public BaseResponse list(UdInfoEntityRequest request, BindingResult bindingResult) { if (bindingResult.hasErrors()) { return ResultVOUtils.error(ResultEnum.PARAM_VERIFY_FALL, bindingResult.getFieldError().getDefaultMessage()); } + Map companyMap = userCompanyService.getCompanyNameMap(); + int offset = (request.getPage() - 1) * request.getLimit(); Page pages = PageHelper.offsetPage(offset, request.getLimit()); List list = udInfoService.list(getQueryWrapper(request)); + for(UdInfoEntity entity:list){ + entity.setCompanyName(entity.getCompanyId() != null?companyMap.get(entity.getCompanyId()):""); + } PageSimpleResponse pageSimpleResponse = new PageSimpleResponse<>(); pageSimpleResponse.setTotal(pages.getTotal()); pageSimpleResponse.setList(list); @@ -71,10 +88,21 @@ public class UdInfoController extends BaseController { if (bindingResult.hasErrors()) { return ResultVOUtils.error(ResultEnum.PARAM_VERIFY_FALL, bindingResult.getFieldError().getDefaultMessage()); } + + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq("uniqueId", entity.getUniqueId()); + if (udInfoService.getOne(queryWrapper)!= null) { + return ResultVOUtils.error(400,"U盾编号已存在"); + } + + String orderNo = gennerOrderUtils.getNo("UD"); AuthAdmin authAdmin = getUser(); entity.setStatus("2"); + entity.setPin("123"); entity.setCheckStatus("2"); entity.setCreateTime(new Date()); + entity.setAllocateStatus("2"); + entity.setSerialNumber(orderNo); entity.setCreateUser(authAdmin.getId()+""); entity.setUpdateTime(new Date()); entity.setUpdateUser( authAdmin.getId()+""); @@ -101,6 +129,9 @@ public class UdInfoController extends BaseController { if (originEntity == null) { return ResultVOUtils.error(ResultEnum.PARAM_VERIFY_FALL); } + if ("key".equals(entity.getType()) || "pin".equals(entity.getType())){ + entity.setCheckStatus("2"); + } AuthAdmin authAdmin = getUser(); entity.setUpdateTime(new Date()); entity.setUpdateUser( authAdmin.getId()+""); @@ -130,6 +161,48 @@ public class UdInfoController extends BaseController { return ResultVOUtils.success(); } + @AuthRuleAnnotation("") + @PostMapping("/check") + @Log(title = "U盾管理", businessType = BusinessType.DELETE) + public BaseResponse check(@RequestBody UdInfoCheckEntityRequest request) { + + UdInfoEntity entity = udInfoService.getById(request.getId()); + if (entity == null) { + return ResultVOUtils.error(ResultEnum.PARAM_VERIFY_FALL); + } + boolean checkStatus = SM2SM3.YtVerfiy(entity.getUserName(),request.getRandomString(), + entity.getPublicKeyX(),entity.getPublicKeyY(),request.getCiphertext()); + if(!checkStatus){ + return ResultVOUtils.error(400,"校验失败"); + } + entity.setCheckStatus("1"); + udInfoService.updateById(entity); + return ResultVOUtils.success(); + } + + @AuthRuleAnnotation("") + @PostMapping("/allocate") + @Log(title = "U盾管理", businessType = BusinessType.DELETE) + public BaseResponse allocate(@RequestBody UdInfoEntity request) { + + UdInfoEntity entity = udInfoService.getById(request.getId()); + if (entity == null) { + return ResultVOUtils.error(ResultEnum.PARAM_VERIFY_FALL); + } + entity.setAllocateStatus("1"); + entity.setAllocateTime(new Date()); + entity.setCompanyId(request.getCompanyId()); + boolean b = udInfoService.updateById(entity); + if (!b) { + return ResultVOUtils.error(ResultEnum.NOT_NETWORK); + } + + return ResultVOUtils.success("分配成功!"); + + } + + + public static QueryWrapper getQueryWrapper(UdInfoEntityRequest request) { UdInfoEntity entity = new UdInfoEntity(); BeanCopyUtils.copy(request, entity); diff --git a/src/main/java/com/glxp/api/controller/ud/UdProducePlanController.java b/src/main/java/com/glxp/api/controller/ud/UdProducePlanController.java index b39edf7..7c95168 100644 --- a/src/main/java/com/glxp/api/controller/ud/UdProducePlanController.java +++ b/src/main/java/com/glxp/api/controller/ud/UdProducePlanController.java @@ -89,7 +89,7 @@ public class UdProducePlanController extends BaseController { if (bindingResult.hasErrors()) { return ResultVOUtils.error(ResultEnum.PARAM_VERIFY_FALL, bindingResult.getFieldError().getDefaultMessage()); } - String orderNo = gennerOrderUtils.getUDNo(); + String orderNo = gennerOrderUtils.getNo("UP"); AuthAdmin authAdmin = getUser(); entity.setRealityNumber(0); entity.setStatus("2"); @@ -153,6 +153,8 @@ public class UdProducePlanController extends BaseController { AuthAdmin authAdmin = getUser(); originEntity.setUpdateTime(new Date()); originEntity.setUpdateUser( authAdmin.getId()+""); + originEntity.setAuditTime(new Date()); + originEntity.setAuditUser( authAdmin.getId()+""); originEntity.setStatus("1"); boolean b = udProducePlanService.updateById(originEntity); if (!b) { diff --git a/src/main/java/com/glxp/api/entity/ud/UdInfoEntity.java b/src/main/java/com/glxp/api/entity/ud/UdInfoEntity.java index 6f230dc..fe0ee91 100644 --- a/src/main/java/com/glxp/api/entity/ud/UdInfoEntity.java +++ b/src/main/java/com/glxp/api/entity/ud/UdInfoEntity.java @@ -25,7 +25,14 @@ public class UdInfoEntity implements Serializable { * 企业id */ @TableField(value = "companyId") - private Integer companyId; + private Long companyId; + + /** + * 使用企业 + */ + @TableField(exist = false) + private String companyName; + /** * 生产计划id @@ -39,6 +46,12 @@ public class UdInfoEntity implements Serializable { @TableField(value = "uniqueId") private String uniqueId; + /** + * type + */ + @TableField(exist = false) + private String type; + /** * U盾序列号 */ @@ -46,10 +59,30 @@ public class UdInfoEntity implements Serializable { private String serialNumber; /** - * 密文字符串 + * pin码 + */ + @TableField(value = "pin") + private String pin; + /** + * 用户名 + */ + @TableField(value = "userName") + private String userName; + /** + * 公钥X字符串 + */ + @TableField(value = "publicKeyX") + private String publicKeyX; + /** + * 公钥Y字符串 + */ + @TableField(value = "publicKeyY") + private String publicKeyY; + /** + * 私钥字符串 */ - @TableField(value = "ciphertext") - private String ciphertext; + @TableField(value = "privateKey") + private String privateKey; /** * 分配时间 diff --git a/src/main/java/com/glxp/api/req/ud/UdInfoCheckEntityRequest.java b/src/main/java/com/glxp/api/req/ud/UdInfoCheckEntityRequest.java new file mode 100644 index 0000000..c8c0df1 --- /dev/null +++ b/src/main/java/com/glxp/api/req/ud/UdInfoCheckEntityRequest.java @@ -0,0 +1,23 @@ +package com.glxp.api.req.ud; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.glxp.api.util.page.ListPageRequest; +import lombok.Data; + +@Data +public class UdInfoCheckEntityRequest { + private Integer id; + /** + * 随机字符串 + */ + @TableField(value = "randomString") + private String randomString; + + /** + * 密文 + */ + @TableField(value = "ciphertext") + private String ciphertext; + +} diff --git a/src/main/java/com/glxp/api/req/ud/UdInfoEntityRequest.java b/src/main/java/com/glxp/api/req/ud/UdInfoEntityRequest.java index 5f816b4..077b00a 100644 --- a/src/main/java/com/glxp/api/req/ud/UdInfoEntityRequest.java +++ b/src/main/java/com/glxp/api/req/ud/UdInfoEntityRequest.java @@ -25,4 +25,11 @@ public class UdInfoEntityRequest extends ListPageRequest { @TableField(value = "serialNumber") private String serialNumber; + + /** + * 分配状态 + */ + @TableField(value = "allocateStatus") + private String allocateStatus; + } diff --git a/src/main/java/com/glxp/api/service/sup/UserCompanyService.java b/src/main/java/com/glxp/api/service/sup/UserCompanyService.java index 5dc6ee6..2d7746a 100644 --- a/src/main/java/com/glxp/api/service/sup/UserCompanyService.java +++ b/src/main/java/com/glxp/api/service/sup/UserCompanyService.java @@ -9,6 +9,7 @@ import com.glxp.api.req.basic.ProductInfoFilterRequest; import com.glxp.api.res.sup.UserCompanyResponse; import java.util.List; +import java.util.Map; public interface UserCompanyService extends IService { @@ -20,4 +21,5 @@ public interface UserCompanyService extends IService { UserCompanyResponse filterCompanyInfo(FilterUserComapanyRequest filterUserComapanyRequest); + Map getCompanyNameMap(); } diff --git a/src/main/java/com/glxp/api/service/sup/impl/UserCompanyServiceImpl.java b/src/main/java/com/glxp/api/service/sup/impl/UserCompanyServiceImpl.java index 57a2ced..17439e0 100644 --- a/src/main/java/com/glxp/api/service/sup/impl/UserCompanyServiceImpl.java +++ b/src/main/java/com/glxp/api/service/sup/impl/UserCompanyServiceImpl.java @@ -1,8 +1,11 @@ package com.glxp.api.service.sup.impl; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.github.pagehelper.PageHelper; +import com.glxp.api.entity.auth.AuthAdmin; import com.glxp.api.entity.basic.ProductInfoEntity; import com.glxp.api.entity.sup.UserCompanyEntity; +import com.glxp.api.req.auth.FilterAuthUserRequest; import com.glxp.api.req.auth.FilterUserComapanyRequest; import com.glxp.api.req.basic.ProductInfoFilterRequest; import com.glxp.api.res.sup.UserCompanyResponse; @@ -14,6 +17,8 @@ import com.glxp.api.service.sup.UserCompanyService; import javax.annotation.Resource; import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; @Service public class UserCompanyServiceImpl extends ServiceImpl implements UserCompanyService { @@ -55,4 +60,12 @@ public class UserCompanyServiceImpl extends ServiceImpl getCompanyNameMap() { + List list = userCompanyMapper.selectList(new QueryWrapper<>()); + + return list.stream().collect(Collectors.toMap(UserCompanyEntity::getId, UserCompanyEntity::getCompanyName)); + + } } diff --git a/src/main/java/com/glxp/api/service/system/CompanyService.java b/src/main/java/com/glxp/api/service/system/CompanyService.java index 8dcc89d..dd9517c 100644 --- a/src/main/java/com/glxp/api/service/system/CompanyService.java +++ b/src/main/java/com/glxp/api/service/system/CompanyService.java @@ -2,6 +2,8 @@ package com.glxp.api.service.system; import com.glxp.api.entity.system.CompanyEntity; +import java.util.Map; + public interface CompanyService { CompanyEntity findCompany(); @@ -9,5 +11,4 @@ public interface CompanyService { boolean modifyCompany(CompanyEntity companyEntity); CompanyEntity findCompany(String CustomerId); - } diff --git a/src/main/java/com/glxp/api/service/system/impl/CompanyServiceImpl.java b/src/main/java/com/glxp/api/service/system/impl/CompanyServiceImpl.java index 6d86b5c..61e44d2 100644 --- a/src/main/java/com/glxp/api/service/system/impl/CompanyServiceImpl.java +++ b/src/main/java/com/glxp/api/service/system/impl/CompanyServiceImpl.java @@ -3,8 +3,10 @@ package com.glxp.api.service.system.impl; import com.github.pagehelper.PageHelper; import com.glxp.api.dao.system.CompanyDao; +import com.glxp.api.entity.auth.AuthAdmin; import com.glxp.api.entity.system.CompanyEntity; +import com.glxp.api.req.auth.FilterAuthUserRequest; import com.glxp.api.service.system.CompanyService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -12,6 +14,8 @@ import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; @Service @Transactional(rollbackFor = Exception.class) @@ -37,4 +41,5 @@ public class CompanyServiceImpl implements CompanyService { public CompanyEntity findCompany(String CustomerId) { return companyDao.findCompany2(CustomerId); } + } diff --git a/src/main/java/com/glxp/api/util/GennerOrderUtils.java b/src/main/java/com/glxp/api/util/GennerOrderUtils.java index 5ce7b09..ff81710 100644 --- a/src/main/java/com/glxp/api/util/GennerOrderUtils.java +++ b/src/main/java/com/glxp/api/util/GennerOrderUtils.java @@ -135,8 +135,8 @@ public class GennerOrderUtils { * * @return */ - public String getUDNo() { - String orderNo = createRecordOrderNo(new OrderNoTypeBean("UD", "yyyyMMdd")); + public String getNo(String prefix) { + String orderNo = createRecordOrderNo(new OrderNoTypeBean(prefix, "yyyyMMdd")); return orderNo; } diff --git a/src/main/java/com/glxp/api/util/SoftKey.java b/src/main/java/com/glxp/api/util/SoftKey.java index 7eca206..3a11da3 100644 --- a/src/main/java/com/glxp/api/util/SoftKey.java +++ b/src/main/java/com/glxp/api/util/SoftKey.java @@ -4,309 +4,6 @@ import cn.hutool.core.util.IdUtil; public class SoftKey { - private String myhex(byte indata) - { - String outstring; - outstring=String.format("%X",indata); - if(outstring.length()<2)outstring="0"+outstring; - return outstring; - } - //若某字节为负数则需将其转成无符号正数 - private long conver(byte temp){ - long tempInt = (int)temp; - if(tempInt < 0){ - tempInt += 256; - } - return tempInt; - } - - //以下用于将16进制字符串转化为无符号长整型 - private int HexToInt(String s) - { - String [] hexch = { "0", "1", "2", "3", "4", "5", "6", "7", - "8", "9", "A", "B", "C", "D", "E", "F"}; - int i, j; - int r, n, k; - String ch; - - k = 1; r = 0; - for (i = s.length(); i > 0; i--) - { - ch = s.substring(i - 1, i-1+1); - n = 0; - for (j = 0; j < 16; j++) - { - if (ch.compareToIgnoreCase(hexch[j]) ==0 ) - { - n = j; - } - } - r += (n * k); - k *= 16; - } - return r; - } - - - public String StrEnc(String InString , String Key)//使用增强算法,加密字符串 - { - - byte [] b,outb; - byte []temp_b=InString.getBytes(); - byte [] temp=new byte[8],outtemp=new byte[8]; - int n,i,nlen,outlen; - String outstring; - - nlen = temp_b.length; - nlen=nlen+1; - if( nlen < 8 ) - outlen = 8; - else - outlen = nlen; - b=new byte[outlen]; - outb=new byte[outlen]; - - for(n=0;n 0) - { - sum = (cnDelta + sum)& mask; - - temp = (z << 4) & mask; - temp = (temp + a) & mask; - temp_1 = (z + sum) & mask; - temp = (temp ^ temp_1) & mask; - temp_1 = (z >> 5) & mask; - temp_1 = (temp_1 + b) & mask; - temp = (temp ^ temp_1) & mask; - temp = (temp + y) & mask; - y = temp & mask; - /*y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); */ - - temp = (y << 4) & mask; - temp = (temp + c) & mask; - temp_1 = (y + sum) & mask; - temp = (temp ^ temp_1) & mask; - temp_1 = (y >> 5) & mask; - temp_1 = (temp_1 + d) & mask; - temp = (temp ^ temp_1) & mask; - temp = (z + temp) & mask; - z = temp & mask; - /* z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); */ - n = n - 1; - - } - for(n = 0;n<=3;n++) - { - outb[n] = (byte)((y >>> (n * 8)) & 255); - outb[n + 4] =(byte)((z >>> (n * 8)) & 255); - } - } - - public void DeCode(byte[] inb, byte[] outb, String Key ) - { - - long cnDelta,y,z,a,b,c,d,temp_2; - long [] buf=new long[16]; - int n,i,nlen; - long sum; - long temp,temp_1; - - long mask=4294967295L; - - //UInt32 temp, temp_1; - String temp_String ; - - - cnDelta = 2654435769L; - sum = 3337565984L; - - nlen = Key.length(); - i = 0; - for( n = 1 ;n<= nlen ;n=n+2) - { - temp_String =Key.substring(n-1, n-1+2); - buf[i] =HexToInt(temp_String); - i = i + 1; - } - a = 0 ; b = 0 ; c = 0 ; d = 0; - for(n = 0;n<=3;n++) - { - a = (buf[n] << (n * 8)) | a; - b = (buf[n + 4] << (n * 8)) | b; - c = (buf[n + 4 + 4] << (n * 8)) | c; - d = (buf[n + 4 + 4 + 4] << (n * 8)) | d; - } - - - y = 0; - z = 0; - for(n = 0;n<=3;n++) - { - temp_2 = conver(inb[n]); - y = (temp_2 << (n * 8)) | y; - temp_2 = conver(inb[n + 4]); - z = (temp_2 << (n * 8)) | z; - } - - - n = 32; - - while (n > 0) - { - - - temp = (y << 4) & mask; - temp = (temp + c) & mask; - temp_1 = (y + sum) & mask; - temp = (temp ^ temp_1) & mask; - temp_1 = (y >> 5) & mask; - temp_1 = (temp_1 + d) & mask; - temp = (temp ^ temp_1) & mask; - temp = (z - temp) & mask; - z = temp & mask; - /* z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); */ - - temp = (z << 4) & mask; - temp = (temp + a) & mask; - temp_1 = (z + sum) & mask; - temp = (temp ^ temp_1) & mask; - temp_1 = (z >> 5) & mask; - temp_1 = (temp_1 + b) & mask; - temp = (temp ^ temp_1) & mask; - temp = (y - temp ) & mask; - y = temp & mask; - /*y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); */ - - sum = (sum-cnDelta)& mask; - n = n - 1; - - } - for(n = 0;n<=3;n++) - { - outb[n] = (byte)((y >>> (n * 8)) & 255); - outb[n + 4] =(byte)((z >>> (n * 8)) & 255); - } - } - - public static void main (String[] args) - { - System.out.println(IdUtil.simpleUUID()); - SoftKey mysoftkey = new SoftKey(); - String InString,Outstring,Outstring_2; - InString="1122222222"; - Outstring=mysoftkey.StrEnc(InString,"5cb4b5fcfe474657b5621f34d0ea6df9"); - Outstring_2=mysoftkey.StrDec(Outstring,"5cb4b5fcfe474657b5621f34d0ea6df9"); - System.out.println(Outstring); - System.out.println(Outstring_2); - - - } } diff --git a/src/main/java/com/glxp/api/util/sm2/ECConstants.java b/src/main/java/com/glxp/api/util/sm2/ECConstants.java new file mode 100644 index 0000000..9bcf6ba --- /dev/null +++ b/src/main/java/com/glxp/api/util/sm2/ECConstants.java @@ -0,0 +1,10 @@ +package com.glxp.api.util.sm2; + +import java.math.BigInteger; + +public interface ECConstants +{ + public static final BigInteger ZERO = BigInteger.valueOf(0); + public static final BigInteger ONE = BigInteger.valueOf(1); + +} diff --git a/src/main/java/com/glxp/api/util/sm2/ECCurve.java b/src/main/java/com/glxp/api/util/sm2/ECCurve.java new file mode 100644 index 0000000..cc71234 --- /dev/null +++ b/src/main/java/com/glxp/api/util/sm2/ECCurve.java @@ -0,0 +1,116 @@ +package com.glxp.api.util.sm2; + + +import java.math.BigInteger; + +/** + * base class for an elliptic curve + */ +public abstract class ECCurve +{ + BigInteger q; + ECFieldElement a, b; + + public ECCurve(BigInteger q, BigInteger a, BigInteger b) + { + this.q = q; + this.a = fromBigInteger(a); + this.b = fromBigInteger(b); + } + + public abstract ECFieldElement fromBigInteger(BigInteger x); + + public abstract ECPoint decodePoint(byte[] encoded); + + public ECFieldElement getA() + { + return a; + } + + public ECFieldElement getB() + { + return b; + } + + /** + * Elliptic curve over Fp + */ + public static class Fp extends ECCurve + { + public Fp(BigInteger q, BigInteger a, BigInteger b) + { + super(q, a, b); + } + + public BigInteger getQ() + { + return q; + } + + public ECFieldElement fromBigInteger(BigInteger x) + { + return new ECFieldElement.Fp(this.q, x); + } + + /** + * decode a point on this curve which has been encoded using + * point compression (X9.62 s 4.2.1 pg 17) returning the point. + */ + public ECPoint decodePoint(byte[] encoded) + { + ECPoint p = null; + + switch (encoded[0]) + { + // compressed + case 0x02: + case 0x03: + int ytilde = encoded[0] & 1; + byte[] i = new byte[encoded.length - 1]; + + System.arraycopy(encoded, 1, i, 0, i.length); + + ECFieldElement x = new ECFieldElement.Fp(this.q, new BigInteger(1, i)); + ECFieldElement alpha = x.multiply(x.square()).add(x.multiply(a).add(b)); + ECFieldElement beta = alpha.sqrt(); + + // + // if we can't find a sqrt we haven't got a point on the + // curve - run! + // + if (beta == null) + { + throw new RuntimeException("Invalid point compression"); + } + + int bit0 = (beta.toBigInteger().testBit(0) ? 0 : 1); + + if ( bit0 == ytilde ) + { + p = new ECPoint.Fp(this, x, beta); + } + else + { + p = new ECPoint.Fp(this, x, + new ECFieldElement.Fp(this.q, q.subtract(beta.toBigInteger()))); + } + break; + case 0x04: + byte[] xEnc = new byte[(encoded.length - 1) / 2]; + byte[] yEnc = new byte[(encoded.length - 1) / 2]; + + System.arraycopy(encoded, 1, xEnc, 0, xEnc.length); + System.arraycopy(encoded, xEnc.length + 1, yEnc, 0, yEnc.length); + + p = new ECPoint.Fp(this, + new ECFieldElement.Fp(this.q, new BigInteger(1, xEnc)), + new ECFieldElement.Fp(this.q, new BigInteger(1, yEnc))); + break; + default: + throw new RuntimeException("Invalid point encoding 0x" + Integer.toString(encoded[0], 16)); + } + + return p; + } + } +} diff --git a/src/main/java/com/glxp/api/util/sm2/ECFieldElement.java b/src/main/java/com/glxp/api/util/sm2/ECFieldElement.java new file mode 100644 index 0000000..e6a5bee --- /dev/null +++ b/src/main/java/com/glxp/api/util/sm2/ECFieldElement.java @@ -0,0 +1,120 @@ +package com.glxp.api.util.sm2; + +import java.math.BigInteger; + +public abstract class ECFieldElement + implements ECConstants +{ + BigInteger x; + BigInteger p; + + protected ECFieldElement(BigInteger q, BigInteger x) + { + if (x.compareTo(q) >= 0) + { + throw new IllegalArgumentException("x value too large in field element"); + } + + this.x = x; + this.p = q; // curve.getQ(); + } + + public BigInteger toBigInteger() + { + return x; + } + + public boolean equals(Object other) + { + if ( other == this ) + return true; + + if ( !(other instanceof ECFieldElement) ) + return false; + + ECFieldElement o = (ECFieldElement)other; + return p.equals(o.p) && x.equals(o.x); + } + + public abstract String getFieldName(); + public abstract ECFieldElement add(ECFieldElement b); + public abstract ECFieldElement subtract(ECFieldElement b); + public abstract ECFieldElement multiply(ECFieldElement b); + public abstract ECFieldElement divide(ECFieldElement b); + public abstract ECFieldElement negate(); + public abstract ECFieldElement square(); + public abstract ECFieldElement invert(); + public abstract ECFieldElement sqrt(); + + public static class Fp extends ECFieldElement + { + /** + * return the field name for this field. + * + * @return the string "Fp". + */ + public String getFieldName() + { + return "Fp"; + } + + public Fp(BigInteger q, BigInteger x) + { + super(q, x); + } + + public ECFieldElement add(ECFieldElement b) + { + return new Fp(p, x.add(b.x).mod(p)); + } + + public ECFieldElement subtract(ECFieldElement b) + { + return new Fp(p, x.subtract(b.x).mod(p)); + } + + public ECFieldElement multiply(ECFieldElement b) + { + return new Fp(p, x.multiply(b.x).mod(p)); + } + + public ECFieldElement divide(ECFieldElement b) + { + return new Fp(p, x.multiply(b.x.modInverse(p)).mod(p)); + } + + public ECFieldElement negate() + { + return new Fp(p, x.negate().mod(p)); + } + + public ECFieldElement square() + { + return new Fp(p, x.multiply(x).mod(p)); + } + + public ECFieldElement invert() + { + return new Fp(p, x.modInverse(p)); + } + + // D.1.4 91 + /** + * return a sqrt root - the routine verifies that the calculation + * returns the right value - if none exists it returns null. + */ + public ECFieldElement sqrt() + { + // p mod 4 == 3 + if ( p.testBit(1) ) + { + // z = g^(u+1) + p, p = 4u + 3 + ECFieldElement z = new Fp(p, x.modPow(p.shiftRight(2).add(ONE), p)); + + return z.square().equals(this) ? z : null; + } + + throw new RuntimeException("not done yet"); + } + } +} diff --git a/src/main/java/com/glxp/api/util/sm2/ECPoint.java b/src/main/java/com/glxp/api/util/sm2/ECPoint.java new file mode 100644 index 0000000..ac6d63b --- /dev/null +++ b/src/main/java/com/glxp/api/util/sm2/ECPoint.java @@ -0,0 +1,149 @@ +package com.glxp.api.util.sm2; + +import java.math.BigInteger; + +/** + * base class for points on elliptic curves. + */ +public abstract class ECPoint +{ + ECCurve curve; + ECFieldElement x; + ECFieldElement y; + + protected ECPoint(ECCurve curve, ECFieldElement x, ECFieldElement y) + { + this.curve = curve; + this.x = x; + this.y = y; + } + + public ECFieldElement getX() + { + return x; + } + + public ECFieldElement getY() + { + return y; + } + + public boolean equals( + Object other) + { + if ( other == this ) + return true; + + if ( !(other instanceof ECPoint) ) + return false; + + ECPoint o = (ECPoint)other; + + return x.equals(o.x) && y.equals(o.y); + } + + public abstract byte[] getEncoded(); + + public abstract ECPoint add(ECPoint b); + public abstract ECPoint subtract(ECPoint b); + public abstract ECPoint twice(); + public abstract ECPoint multiply(BigInteger b); + + /** + * Elliptic curve points over Fp + */ + public static class Fp extends ECPoint + { + public Fp(ECCurve curve, ECFieldElement x, ECFieldElement y) + { + super(curve, x, y); + } + + /** + * return the field element encoded with point compression. (S 4.3.6) + */ + public byte[] getEncoded() + { + byte PC; + + if (this.getY().toBigInteger().testBit(0)) + { + PC = 0x02; + } + else + { + PC = 0x03; + } + + byte[] X = this.getX().toBigInteger().toByteArray(); + byte[] PO = new byte[X.length + 1]; + + PO[0] = PC; + System.arraycopy(X, 0, PO, 1, X.length); + + return PO; + } + + // B.3 pg 62 + public ECPoint add(ECPoint b) + { + ECFieldElement gamma = b.y.subtract(y).divide(b.x.subtract(x)); + + ECFieldElement x3 = gamma.multiply(gamma).subtract(x).subtract(b.x); + ECFieldElement y3 = gamma.multiply(x.subtract(x3)).subtract(y); + + return new ECPoint.Fp(curve, x3, y3); + } + + // B.3 pg 62 + public ECPoint twice() + { + ECFieldElement TWO = curve.fromBigInteger(BigInteger.valueOf(2)); + ECFieldElement THREE = curve.fromBigInteger(BigInteger.valueOf(3)); + ECFieldElement gamma = x.multiply(x).multiply(THREE).add(curve.a).divide(y.multiply(TWO)); + + ECFieldElement x3 = gamma.multiply(gamma).subtract(x.multiply(TWO)); + ECFieldElement y3 = gamma.multiply(x.subtract(x3)).subtract(y); + + return new ECPoint.Fp(curve, x3, y3); + } + + // D.3.2 pg 102 (see Note:) + public ECPoint subtract(ECPoint p2) + { + return add(new ECPoint.Fp(curve, p2.x, p2.y.negate())); + } + + // D.3.2 pg 101 + public ECPoint multiply(BigInteger k) + { + // BigInteger e = k.mod(n); // n == order this + BigInteger e = k; + + BigInteger h = e.multiply(BigInteger.valueOf(3)); + + ECPoint R = this; + + for (int i = h.bitLength() - 2; i > 0; i--) + { + R = R.twice(); + + if ( h.testBit(i) && !e.testBit(i) ) + { + //System.out.print("+"); + R = R.add(this); + } + else if ( !h.testBit(i) && e.testBit(i) ) + { + //System.out.print("-"); + R = R.subtract(this); + } + // else + // System.out.print("."); + } + // System.out.println(); + + return R; + } + } +} diff --git a/src/main/java/com/glxp/api/util/sm2/SM2Result.java b/src/main/java/com/glxp/api/util/sm2/SM2Result.java new file mode 100644 index 0000000..12aabf8 --- /dev/null +++ b/src/main/java/com/glxp/api/util/sm2/SM2Result.java @@ -0,0 +1,27 @@ + +package com.glxp.api.util.sm2; + + +import java.math.BigInteger; + +public class SM2Result +{ + public SM2Result() + { + } + + + // 签名、验签 + public BigInteger r; + public BigInteger s; + public BigInteger R; + + // 密钥交换 + public byte[] sa; + public byte[] sb; + public byte[] s1; + public byte[] s2; + + public ECPoint keyra; + public ECPoint keyrb; +} \ No newline at end of file diff --git a/src/main/java/com/glxp/api/util/sm2/SM2SM3.java b/src/main/java/com/glxp/api/util/sm2/SM2SM3.java new file mode 100644 index 0000000..9c63427 --- /dev/null +++ b/src/main/java/com/glxp/api/util/sm2/SM2SM3.java @@ -0,0 +1,647 @@ +package com.glxp.api.util.sm2; +import com.glxp.api.util.sm2.SM2Result; + +import java.math.BigInteger; + + + +public class SM2SM3 { + private static final int BYTE_LENGTH = 32; + private static final int BLOCK_LENGTH = 64; + private static final int BUFFER_LENGTH = 64*2; + private byte[] xBuf = new byte[BUFFER_LENGTH]; + private int xBufOff; + private byte[] V = SM3.iv; + private int cntBlock = 0; + + public static BigInteger ecc_p; + public static BigInteger ecc_a; + public static BigInteger ecc_b; + public static BigInteger ecc_n; + public static BigInteger ecc_gx; + public static BigInteger ecc_gy; + + public static ECCurve ecc_curve; + public static ECPoint ecc_point_g; + + public SM2SM3() { + } + + + public static byte[] GetE(byte[] z, byte[] HashMsgValue) + { + SM2SM3 digest = new SM2SM3(); + + digest.update(z, 0, z.length); + + digest.update(HashMsgValue, 0, 32); + + byte[] md = new byte[32]; + digest.doFinal(md, 0); + return md; + + } + + public static byte[] GetMsgHash(String msg) + { + SM2SM3 digest = new SM2SM3(); + byte[] p = msg.getBytes(); + digest.update(p, 0, p.length); + + byte[] md = new byte[32]; + digest.doFinal(md, 0); + return md; + + } + + public static boolean YtVerfiy(String id, String InString, String PubKeyX,String PubKeyY,String VerfiySign ) + { + + SM2SM3 digest = new SM2SM3(); + BigInteger affineX = new BigInteger(PubKeyX, 16); + BigInteger affineY = new BigInteger(PubKeyY, 16); + + byte[] z = digest.Sm2GetZ(affineX, affineY, id.getBytes()); + + byte []MsgHash=GetMsgHash(InString); + + byte []E=GetE(z,MsgHash); + + BigInteger r = new BigInteger(VerfiySign.substring(0, 64), 16); + BigInteger s = new BigInteger(VerfiySign.substring(64, 128), 16); + + return digest.subSm2Verify(E,affineX,affineY, r, s ); + + + } + + private static boolean subSm2Verify(byte[] md, BigInteger PubKeyX, BigInteger PubKeyY,BigInteger r, BigInteger s) + { + SM2Result sm2Ret= new SM2Result();; + ECFieldElement ecc_gx_fieldelement; + ECFieldElement ecc_gy_fieldelement; + + ecc_gx_fieldelement = new ECFieldElement.Fp(Util.p, Util.Gx); + ecc_gy_fieldelement = new ECFieldElement.Fp(Util.p, Util.Gy); + + ecc_curve = new ECCurve.Fp(Util.p, Util.a, Util.b); + ecc_point_g=new ECPoint.Fp(ecc_curve, ecc_gx_fieldelement, ecc_gy_fieldelement); + + ECFieldElement ecc_kx_fieldelement = new ECFieldElement.Fp(Util.p, PubKeyX); + ECFieldElement ecc_ky_fieldelement = new ECFieldElement.Fp(Util.p, PubKeyY); + ECPoint userKey = new ECPoint.Fp(ecc_curve, ecc_kx_fieldelement, ecc_ky_fieldelement); + + sm2Ret.R = null; + + // e_ + BigInteger e = new BigInteger(1, md); + // t + BigInteger t = r.add(s).mod(Util.n); + + if (t.equals(BigInteger.ZERO)) + return false; + + // x1y1 + ECPoint x1y1 = ecc_point_g.multiply(s); + x1y1 = x1y1.add(userKey.multiply(t)); + + // R + sm2Ret.R = e.add(x1y1.x.toBigInteger()).mod(Util.n); + + if (r.equals(sm2Ret.R)) + { + return true; + } + return false; + } + + /** + * SM3结果输出 + * @param out 保存SM3结构的缓冲区 + * @param outOff 缓冲区偏移量 + * @return + */ + public int doFinal(byte[] out, int outOff) { + byte[] tmp = doFinal(); + System.arraycopy(tmp, 0, out, 0, tmp.length); + return BYTE_LENGTH; + } + + public String getAlgorithmName() { + return "SM3"; + } + + public int getDigestSize() { + return BYTE_LENGTH; + } + + public void reset() { + xBufOff = 0; + cntBlock = 0; + V = SM3.iv; + } + + + /** + * 明文输入 + * @param in 明文输入缓冲区 + * @param inOff 缓冲区偏移量 + * @param len 明文长度 + */ + public void update(byte[] in, int inOff, int len) { + if(xBufOff+len > BUFFER_LENGTH) { + int tmpLen = xBufOff+len-BUFFER_LENGTH; + System.arraycopy(in, inOff, xBuf, xBufOff, BUFFER_LENGTH-xBufOff); + doUpdate(); + xBufOff = 0; + int i=1; + while(tmpLen > BUFFER_LENGTH) { + tmpLen -= BUFFER_LENGTH; + System.arraycopy(in, inOff+BUFFER_LENGTH*i, xBuf, xBufOff, BUFFER_LENGTH-xBufOff); + doUpdate(); + xBufOff = 0; + i++; + } + System.arraycopy(in, inOff+len-tmpLen, xBuf, xBufOff, tmpLen); + xBufOff += tmpLen; + + } else if(xBufOff+len == BUFFER_LENGTH) { + System.arraycopy(in, inOff, xBuf, xBufOff, len); + doUpdate(); + xBufOff = 0; + } else { + System.arraycopy(in, inOff, xBuf, xBufOff, len); + xBufOff += len; + } + } + + private void doUpdate() { + byte[] B = new byte[BLOCK_LENGTH]; + for(int i=0; i=0 && j<=15) { + return FF1j(X, Y, Z); + } else { + return FF2j(X, Y, Z); + } + } + private static int GGj(int X, int Y, int Z, int j) { + if(j>=0 && j<=15) { + return GG1j(X, Y, Z); + } else { + return GG2j(X, Y, Z); + } + } + /***********************************************/ + // 逻辑位运算函数 + private static int FF1j(int X, int Y, int Z) { + int tmp = X ^ Y ^ Z; + + return tmp; + } + + private static int FF2j(int X, int Y, int Z) { + int tmp = ( (X & Y) | (X & Z) | (Y & Z) ); + + return tmp; + } + + private static int GG1j(int X, int Y, int Z) { + int tmp = X ^ Y ^ Z; + + return tmp; + } + + private static int GG2j(int X, int Y, int Z) { + int tmp = (X & Y) | (~X & Z) ; + + return tmp; + } + + private static int P0(int X) { + int t = X ^ bitCycleLeft(X, 9) ^ bitCycleLeft(X, 17); + + return t; + } + + private static int P1(int X) { + int t = X ^ bitCycleLeft(X, 15) ^ bitCycleLeft(X, 23); + + return t; + } + + /** + * 对最后一个分组字节数据padding + * @param in + * @param bLen 分组个数 + * @return + */ + public static byte[] padding(byte[] in, int bLen) { + //第一bit为1 所以长度=8 * in.length+1 k为所补的bit k+1/8 为需要补的字节 + int k = 448 - (8 * in.length+1) % 512; + if( k < 0) { + k = 960 - (8 * in.length+1) % 512; + } + k += 1; + byte[] padd = new byte[k/8]; + padd[0] = (byte)0x80; + long n = in.length * 8+bLen*512; + //64/8 字节 长度 + //k/8 字节padding + byte[] out = new byte[in.length+k/8+64/8]; + int pos = 0; + System.arraycopy(in, 0, out, 0, in.length); + pos += in.length; + System.arraycopy(padd, 0, out, pos, padd.length); + pos += padd.length; + byte[] tmp = back(Util.LongToByte(n)); + System.arraycopy(tmp, 0, out, pos, tmp.length); + + return out; + } + + /** + * 字节数组逆序 + * @param in + * @return + */ + private static byte[] back(byte[] in) { + byte[] out = new byte[in.length]; + for(int i=0; i 0) { + tmp = byteCycleLeft(tmp, byteLen); + } + + if(len > 0) { + tmp = bitSmall8CycleLeft(tmp, len); + } + + return bigEndianByteToInt(tmp); + } + + private static byte[] bitSmall8CycleLeft(byte[] in, int len) { + byte[] tmp = new byte[in.length]; + int t1, t2, t3; + for(int i=0; i>(8-len)); + t3 = (byte) (t1 | t2); + tmp[i] = (byte)t3; + } + + + return tmp; + } + + private static byte[] byteCycleLeft(byte[] in, int byteLen) { + byte[] tmp = new byte[in.length]; + System.arraycopy(in, byteLen, tmp, 0, in.length-byteLen); + System.arraycopy(in, 0, tmp, in.length-byteLen, byteLen); + + return tmp; + } + +} + +class Util { + public static BigInteger p = new BigInteger("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", 16); + public static BigInteger a = new BigInteger("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", 16); + public static BigInteger b = new BigInteger("28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", 16); + public static BigInteger n = new BigInteger("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", 16); + public static BigInteger Gx = new BigInteger("32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", 16); + public static BigInteger Gy = new BigInteger("BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0", 16); + public static byte[] getP() { + return p.toByteArray(); + } + public static byte[] getA() { + return asUnsigned32ByteArray(a); + } + public static byte[] getB() { + return asUnsigned32ByteArray(b); + } + public static byte[] getN() { + return asUnsigned32ByteArray(n); + } + public static byte[] getGx() { + return asUnsigned32ByteArray(Gx); + } + public static byte[] getGy() { + return asUnsigned32ByteArray(Gy); + } + + /** + * 整形转换成网络传输的字节流(字节数组)型数据 + * @param num 一个整型数据 + * @return 4个字节的自己数组 + */ + public static byte[] IntToByte(int num) { + byte[] bytes = new byte[4]; + + bytes[0] = (byte)(0xff&(num>>0)); + bytes[1] = (byte)(0xff&(num>>8)); + bytes[2] = (byte)(0xff&(num>>16)); + bytes[3] = (byte)(0xff&(num>>24)); + + return bytes; + } + + /** + * 四个字节的字节数据转换成一个整形数据 + * @param bytes 4个字节的字节数组 + * @return 一个整型数据 + */ + public static int ByteToInt(byte[] bytes) { + int num = 0; + int temp; + temp = (0x000000ff & (bytes[0]))<<0; + num = num | temp; + temp = (0x000000ff & (bytes[1]))<<8; + num = num | temp; + temp = (0x000000ff & (bytes[2]))<<16; + num = num | temp; + temp = (0x000000ff & (bytes[3]))<<24; + num = num | temp; + + return num; + } + + public static byte[] LongToByte(long num) { + byte[] bytes = new byte[8]; + + for(int i=0; i<8; i++) { + bytes[i] = (byte)(0xff&(num>>(i*8))); + } + + return bytes; + } + public static byte[] asUnsigned32ByteArray(BigInteger n) { + return asUnsignedNByteArray(n, 32); + } + public static byte[] asUnsignedNByteArray(BigInteger x, int length) { + if(x == null) { + return null; + } + + byte[] tmp = new byte[length]; + int len = x.toByteArray().length; + if(len > length+1) { + return null; + } + + if(len == length+1) { + if(x.toByteArray()[0] != 0) { + return null; + } else { + System.arraycopy(x.toByteArray(), 1, tmp, 0, length); + return tmp; + } + } else { + System.arraycopy(x.toByteArray(), 0, tmp, length-len, len); + return tmp; + } + + } + + public static void main(String[] args) { + boolean a = SM2SM3.YtVerfiy("mysofkey","123456","67F78ADD4D88ACB96AFA2503E0B9B26A1009212382870411FD4907FBFE5CA9B2","9927B367304065744C85247F4673E890EC77F752DB74F1C0BC1A8157EE9B42E5","2874CFA93EBD563A8A4C4B4D14A072562FB04B14CCD07754713B8A70D61A052A16ACA3A53C7D330D488EA1242BAC85F658A847CA4991D25B8C43ACAA7211C333"); + System.out.println(a); + } + +} diff --git a/src/main/java/com/glxp/api/util/sm2/Test.java b/src/main/java/com/glxp/api/util/sm2/Test.java deleted file mode 100644 index 366e0ae..0000000 --- a/src/main/java/com/glxp/api/util/sm2/Test.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.glxp.api.util.sm2; - -import cn.hutool.core.util.HexUtil; -import cn.hutool.core.util.StrUtil; -import cn.hutool.crypto.BCUtil; -import cn.hutool.crypto.SecureUtil; -import cn.hutool.crypto.SmUtil; -import cn.hutool.crypto.asymmetric.KeyType; -import cn.hutool.crypto.asymmetric.SM2; -import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; -import org.bouncycastle.jce.ECNamedCurveTable; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; -import org.bouncycastle.jce.spec.ECNamedCurveSpec; -import org.bouncycastle.util.encoders.Hex; - -import java.security.*; - -import java.math.BigInteger; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.interfaces.ECPublicKey; -import java.security.spec.*; -import java.util.Base64; - -public class Test { - - public static void main(String[] args) { - - - String text = "wangjing"; - - //使用随机生成的密钥对加密或解密 - System.out.println("使用随机生成的密钥对加密或解密====开始"); - SM2 sm2 = SmUtil.sm2(); - // 公钥加密 - String encryptStr = sm2.encryptBcd(text, KeyType.PublicKey); - System.out.println("公钥加密:" + encryptStr); - //私钥解密 - String decryptStr = StrUtil.utf8Str(sm2.decryptFromBcd(encryptStr, KeyType.PrivateKey)); - System.out.println("私钥解密:" + decryptStr); - System.out.println("使用随机生成的密钥对加密或解密====结束"); - - - //使用自定义密钥对加密或解密 - System.out.println("使用自定义密钥对加密或解密====开始"); - - - - - String hutoolPrivateKeyHex = HexUtil.encodeHexStr(BCUtil.encodeECPrivateKey(sm2.getPrivateKey())); - String hutoolPublicKeyHex = HexUtil.encodeHexStr(((BCECPublicKey) sm2.getPublicKey()).getQ().getEncoded(false)); - String hutoolPublicKeyHexX = HexUtil.encodeHexStr(((BCECPublicKey) sm2.getPublicKey()).getQ().getXCoord().getEncoded()); - String hutoolPublicKeyHexY = HexUtil.encodeHexStr(((BCECPublicKey) sm2.getPublicKey()).getQ().getYCoord().getEncoded()); - - System.out.println(hutoolPrivateKeyHex); - System.out.println(hutoolPublicKeyHex); - System.out.println(hutoolPublicKeyHexX); - System.out.println(hutoolPublicKeyHexY); - - - ECPublicKey publicKey = hexToSM2PublicKey(hutoolPublicKeyHexX, hutoolPublicKeyHexY); - String hutoolPublicKeyHex1 = HexUtil.encodeHexStr(publicKey.getEncoded()); - System.out.println(hutoolPublicKeyHex1); - SM2 sm22 = SmUtil.sm2(hutoolPrivateKeyHex, hutoolPublicKeyHex1); - // 公钥加密 - String encryptStr2 = sm22.encryptBcd(text, KeyType.PublicKey); - System.out.println("公钥加密:" + encryptStr2); - //私钥解密 - String decryptStr2 = StrUtil.utf8Str(sm22.decryptFromBcd(encryptStr2, KeyType.PrivateKey)); - System.out.println("私钥解密:" + decryptStr2); - System.out.println("使用自定义密钥对加密或解密====结束"); - - } - - - public static ECPublicKey hexToSM2PublicKey(String x, String y) { - ECPublicKey pubkey = null; - try { - KeyFactory keyFactory = KeyFactory.getInstance("EC"); - ECPoint ecPoint = new ECPoint( - new BigInteger(x, 16), new BigInteger(y, 16)); - - ECNamedCurveParameterSpec parameterSpec = ECNamedCurveTable.getParameterSpec("sm2p256v1"); - ECNamedCurveSpec spec = new ECNamedCurveSpec("sm2p256v1", parameterSpec.getCurve(), parameterSpec.getG(), parameterSpec.getN(), parameterSpec.getH(), parameterSpec.getSeed()); - - ECPublicKeySpec keySpec = new ECPublicKeySpec(ecPoint, spec); - pubkey = new BCECPublicKey("BC", keySpec, BouncyCastleProvider.CONFIGURATION); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } - - return pubkey; - } - -}