本文不对SM2做过多的介绍,主要介绍java bouncycastle库关于SM2的相关API的使用及注意事项

1. SM2 签名:

注意:

  1)签名格式ASN1(描述了种对数据进行表示、编码、传输和解码的数据格式),包括两个大整数。

  2)注意USER_ID的一致性(规范默认是"1234567812345678"),否则影响验签。

  

主要代码

  1. SM2Signer localSM2Signer = new SM2Signer();
  2. Security.addProvider(new BouncyCastleProvider());
  3. PublicKey publicKey = cert.getPublicKey();
  4. ECPublicKeyParameters param = null;
  5.  
  6. if (publicKey instanceof BCECPublicKey)
  7. {
  8. BCECPublicKey localECPublicKey = (BCECPublicKey)publicKey;
  9. ECParameterSpec localECParameterSpec = localECPublicKey.getParameters();
  10. ECDomainParameters localECDomainParameters = new ECDomainParameters(localECParameterSpec.getCurve(),
  11. localECParameterSpec.getG(), localECParameterSpec.getN());
  12. param = new ECPublicKeyParameters(localECPublicKey.getQ(),localECDomainParameters);
  13. }
  14. ByteArrayInputStream inStream = new ByteArrayInputStream(signdatebyte);
  15. ASN1InputStream asnInputStream = new ASN1InputStream(inStream);
  16. ASN1Primitive derObject = asnInputStream.readObject();
  17. BigInteger R = null;
  18. BigInteger S = null;
  19. if (derObject instanceof ASN1Sequence) {
  20. ASN1Sequence signSequence = (ASN1Sequence) derObject;
  21. Enumeration<ASN1Integer> enumer = signSequence.getObjects();
  22. R = ((ASN1Integer)enumer.nextElement()).getValue();
  23. S = ((ASN1Integer)enumer.nextElement()).getValue();
  24. }
  25. ParametersWithID parametersWithID = new ParametersWithID(param,SM2_USER_ID);
  26. localSM2Signer.init(false, parametersWithID);
  27. boolean res = localSM2Signer.verifySignature(databyte, BigIntegerUtil.toPositiveInteger(R.toByteArray()),
  28. BigIntegerUtil.toPositiveInteger(S.toByteArray()));
  29. return res;

2. SM2 验签:

注意:同签名

主要代码

  1. SM2Signer localSM2Signer = new SM2Signer();
  2. Security.addProvider(new BouncyCastleProvider());
  3. PublicKey publicKey = cert.getPublicKey();
  4. ECPublicKeyParameters param = null;
  5.  
  6. if (publicKey instanceof BCECPublicKey)
  7. {
  8. BCECPublicKey localECPublicKey = (BCECPublicKey)publicKey;
  9. ECParameterSpec localECParameterSpec = localECPublicKey.getParameters();
  10. ECDomainParameters localECDomainParameters = new ECDomainParameters(localECParameterSpec.getCurve(),
  11. localECParameterSpec.getG(), localECParameterSpec.getN());
  12. param = new ECPublicKeyParameters(localECPublicKey.getQ(),localECDomainParameters);
  13. }
  14. ByteArrayInputStream inStream = new ByteArrayInputStream(signdatebyte);
  15. ASN1InputStream asnInputStream = new ASN1InputStream(inStream);
  16. ASN1Primitive derObject = asnInputStream.readObject();
  17. BigInteger R = null;
  18. BigInteger S = null;
  19. if (derObject instanceof ASN1Sequence) {
  20. ASN1Sequence signSequence = (ASN1Sequence) derObject;
  21. Enumeration<ASN1Integer> enumer = signSequence.getObjects();
  22. R = ((ASN1Integer)enumer.nextElement()).getValue();
  23. S = ((ASN1Integer)enumer.nextElement()).getValue();
  24. }
  25. ParametersWithID parametersWithID = new ParametersWithID(param,SM2_USER_ID);
  26. localSM2Signer.init(false, parametersWithID);
  27. boolean res = localSM2Signer.verifySignature(databyte, BigIntegerUtil.toPositiveInteger(R.toByteArray()),
  28. BigIntegerUtil.toPositiveInteger(S.toByteArray()));

3. 加解密

  1. public static String encrypt(String data, PublicKey publicKey)
  2. {
  3.  
  4. ECPublicKeyParameters localECPublicKeyParameters = null;
  5.  
  6. if (publicKey instanceof BCECPublicKey)
  7. {
  8. BCECPublicKey localECPublicKey = (BCECPublicKey)publicKey;
  9. ECParameterSpec localECParameterSpec = localECPublicKey.getParameters();
  10. ECDomainParameters localECDomainParameters = new ECDomainParameters(
  11. localECParameterSpec.getCurve(), localECParameterSpec.getG(),
  12. localECParameterSpec.getN());
  13. localECPublicKeyParameters = new ECPublicKeyParameters(localECPublicKey.getQ(),
  14. localECDomainParameters);
  15. }
  16. SM2Engine localSM2Engine = new SM2Engine();
  17. localSM2Engine.init(true, new ParametersWithRandom(localECPublicKeyParameters,
  18. new SecureRandom()));
  19. byte[] arrayOfByte2;
  20. try
  21. {
  22. arrayOfByte2 = localSM2Engine.processBlock(data.getBytes(), 0, data.getBytes().length);
  23. return new String(Base64.encode(arrayOfByte2));
  24. }
  25. catch (InvalidCipherTextException e)
  26. {
  27.  
  28. e.printStackTrace();
  29. return null;
  30. }
  31.  
  32. }
  33.  
  34. public static String decrypt(String encodedata, PrivateKey privateKey)
  35. {
  36. byte[] encodedataByte = Base64.decode(encodedata.getBytes());
  37. SM2Engine localSM2Engine = new SM2Engine();
  38. BCECPrivateKey sm2PriK = (BCECPrivateKey)privateKey;
  39. ECParameterSpec localECParameterSpec = sm2PriK.getParameters();
  40. ECDomainParameters localECDomainParameters = new ECDomainParameters(
  41. localECParameterSpec.getCurve(), localECParameterSpec.getG(),
  42. localECParameterSpec.getN());
  43. ECPrivateKeyParameters localECPrivateKeyParameters = new ECPrivateKeyParameters(
  44. sm2PriK.getD(), localECDomainParameters);
  45. localSM2Engine.init(false, localECPrivateKeyParameters);
  46. try
  47. {
  48. byte[] arrayOfByte3 = localSM2Engine.processBlock(encodedataByte, 0,
  49. encodedataByte.length);
  50. return new String(arrayOfByte3);
  51. }
  52. catch (InvalidCipherTextException e)
  53. {
  54. e.printStackTrace();
  55. return null;
  56. }
  57.  
  58. }

4. pkcs#7(CMS)格式

可以使用bouncycastle的CMS包下的API进行封装,或者自己实现,或使用j4sign库(基于bouncycastle)实现。这里就不贴代码了。

注意:相关OID

  1. 国密标准GM/T 0010定义的oid如下:
  2. 数据类型data 1.2.156.10197.6.1.4.2.1
  3. 签名数据类型signedData 1.2.156.10197.6.1.4.2.2
  4. 数字信封数据类型envelopedData        1.2.156.10197.6.1.4.2.3
  5. 签名及数字信封数据类型signedAndEnvelopedData                  1.2.156.10197.6.1.4.2.4
  6. 加密数据类型encryptedData 1.2.156.10197.6.1.4.2.5
  7. 密钥协商类型keyAgreementInfo    1.2.156.10197.6.1.4.2.6

参考资料:

1.GM T 0009-2012 SM2密码算法使用规范

2.https://tools.ietf.org/html/rfc2315

3.http://j4sign.sourceforge.net/

4.http://gmssl.org/docs/oid.html

5.https://stackoverflow.com/questions/39925946/generate-cmssigneddata-with-no-private-key-in-java

6.https://github.com/bcgit/bc-java

7.https://www.zhihu.com/question/62639301/answer/214184309

转载请注明原博客地址http://www.cnblogs.com/jeffreyluo/p/sm2forjava.html)

bouncycastle 国密SM2 API的使用的更多相关文章

  1. 推荐一款能支持国密SM2浏览器——密信浏览器

    密信浏览器( MeSince Browser )是基于Chromium开源项目开发的国密安全浏览器,支持国密算法和国密SSL证书,同时也支持国际算法及全球信任SSL证书:密信浏览器使用界面清新,干净. ...

  2. 谈谈PBOC3.0中使用的国密SM2算法

    转载请注明出处 http://blog.csdn.net/pony_maggie/article/details/39780825 作者:小马 一 知识准备 SM2是国密局推出的一种他们自己说具有自主 ...

  3. 一个支持国密SM2/SM3/SM4/SM9/ZUC/SSL的密码工具箱

    转:https://blog.csdn.net/xuq09/article/details/91815366 The GmSSL Project网址:http://gmssl.org/docs/qui ...

  4. java 解析国密SM2算法证书

    首先说明用Java自带的解析x509证书类,是不能解析sm2算法的证书,执行会抛出异常. 用开源库bouncycastle能够解析.详细代码 private byte[] getCSPK(byte[] ...

  5. SM 国密算法踩坑指南

    各位,好久不见~ 最近接手网联的国密改造项目,由于对国密算法比较陌生,前期碰到了一系列国密算法加解密的问题. 所以这次总结一下,分享这个过程遇到的问题,希望帮到大家. 国密 什么是国密算法? 国密就是 ...

  6. 20155206赵飞 基于《Arm试验箱的国密算法应用》课程设计个人报告

    20155206赵飞 基于<Arm试验箱的国密算法应用>课程设计个人报告 课程设计中承担的任务 完成试验箱测试功能1,2,3 . 1:LED闪烁实验 一.实验目的  学习GPIO原理  ...

  7. 《基于Arm实验箱的国密算法应用》课程设计 结题报告

    <基于Arm实验箱的国密算法应用>课程设计 结题报告 小组成员姓名:20155206赵飞 20155220吴思其 20155234昝昕明 指导教师:娄嘉鹏 设计方案 题目要求:基于Arm实 ...

  8. 2017-2018-2 20179204《网络攻防实践》第十三周学习总结 python实现国密算法

    国密商用算法是指国密SM系列算法,包括基于椭圆曲线的非对称公钥密码SM2算法.密码杂凑SM3算法.分组密码SM4算法,还有只以IP核形式提供的非公开算法流程的对称密码SM1算法等. 第1节 SM2非对 ...

  9. 国密SSL证书免费试用申请指南

    沃通提供国密SSL证书免费申请试用服务,一次申请可同时签发SM2/RSA双算法证书,试用周期1个月,用于测试国密SM2 SSL证书的运行效果和SM2/RSA双证书部署效果. 试用产品:SM2/RSA双 ...

随机推荐

  1. 记一次redis挂机导致的服务雪崩事故~不对,是故事

    事故时常有,最近特别多!但每次事故总会有人出来背锅!如果不是自己的锅,解决了对自己是一种成长,如果是自己的锅,恐怕锅大了,就得走人了,哈哈哈... 这不,最近又出了一个锅:从周五开始,每天到11点就不 ...

  2. python webserver, based on SimpleHTTPServer

    #-*- coding:utf-8 -*- #author: lichmama #email: nextgodhand@163.com #filename: httpd.py import io im ...

  3. xhr.readyState的就绪状态

    0:初始化,XMLHttpRequest对象还没有完成初始化 1:载入,XMLHttpRequest对象开始发送请求 2:载入完成,XMLHttpRequest对象的请求发送完成 3:解析,XMLHt ...

  4. str-字符串功能介绍

    叨逼叨:字符串的各个功能修改不是本身,本身不变,会产生新的值,需要赋值给新的变量来接收 以下 "举例" 是解释每个功能的实例   "举例"下一行是pycharm ...

  5. linux中日志介绍

    linux日志 linux日志大多是以明文存储,一般存储在/var/log目录中,linux系统中主要有三个日志子系统:连接时间日志,进程统计日志,错误日志. 连接时间日志 连接时间日志是有多个程序执 ...

  6. java三大框架介绍

    常听人提起三大框架,关于三大框架,做了如下了解: 三大框架:Struts+Hibernate+Spring java三大框架主要用来做WEN应用. Struts主要负责表示层的显示 Spring利用它 ...

  7. python全栈阶段测试(一)

    1.执行Python脚本的两种方式 如果想要永久保存代码,就要用文件的方式 如果想要调试代码,就要用交互式的方式 2.Pyhton单行注释和多行注释分别用什么? 单行注释:# 多行注释: '' &qu ...

  8. FreeRTOS——队列管理

    1. 队列主要用于任务与任务.中断与任务之间的消息传递. 2. 创建队列时,请注意队列中数据单元的长度. 3. 通常情况,队列被作为FIFO(先进先出)使用,即数据从队列尾写入,从队列首读.当然,数据 ...

  9. hbase集群导入csv文件

    小数据文件导入: 样例 hbase  org.apache.hadoop.hbase.mapreduce.ImportTsv  -Dimporttsv.separator="," ...

  10. 【PHP】打印输出var_dump+echo+print_r

    var_dump 判断一个变量的类型与长度如:<?$a = 1;$b = 't';echo var_dump($ta,$tb); // 结果为 int(123) string(3) " ...