实现了ASN.1语法,对数字证书进行解析,并对RSA WITH SHA256的证书进行验签。使用.net core c#编写。

ASN.1语法解析代码

using System;
using System.Collections.Generic;
using System.Numerics;
using System.Globalization;namespace ASN1
{enum TLVType {Boolean = 0x1,Integer = 0x2,BitString = 0x3,OctetString = 0x4,Null = 0x5,Object = 0x6,PrintableString = 0x13,UTCTime = 0x17,Sequence = 0x30,Set = 0x31,Version = 0xA0,Extensions = 0xA3}class Bytes{public static byte[] SubBytes(byte[] bytes, int start){byte[] t = new byte[bytes.Length - start];Array.Copy(bytes, start, t, 0, t.Length);return t;}public static byte[] SubBytes(byte[] bytes, int start, int len){byte[] t = new byte[len];Array.Copy(bytes, start, t, 0, t.Length);return t;}public static byte[] Concat(byte[] b1, byte[] b2){byte[] t = new byte[b1.Length + b2.Length];Array.Copy(b1, t, b1.Length);Array.Copy(b2, 0, t, b1.Length, b2.Length);return t;}}abstract class TLV{protected byte _tag;protected byte[] _length = null;protected byte[] _data = null;protected byte[] _ori = null;protected TLV(byte[] buf){_tag = buf[0];int lengthSize = getTLVLengthSize(Bytes.SubBytes(buf, 1));_length = Bytes.SubBytes(buf, 1, lengthSize);int dataSize = getTLVDataSize(_length);_data = Bytes.SubBytes(buf, 1 + lengthSize, dataSize);_ori = Bytes.SubBytes(buf, 0, 1 + lengthSize + _data.Length);}public byte Tag {  get { return _tag;  } }public byte[] Data {  get { return _data;  } }public int LenthSize { get { return _length.Length;  } }public int DataSize {  get { return  _data.Length;  } }public int Size { get { return 1 + _length.Length + _data.Length; } }public byte[] Original { get { return _ori;  } }int getTLVDataSize(byte[] buf){int len = 0;if (buf[0] < 0x80){len = buf[0];}else if (buf[0] > 0x80){int i = buf[0] - 0x80;if (i > 0) len = buf[1];if (i > 1) len = len << 8 | buf[2];if (i > 2) len = len << 8 | buf[3];if (i > 3) len = len << 8 | buf[4];}else if (buf[0] == 0x80){int i = 0;while (buf[i + 2] != 0 && buf[i + 3] != 0){i++;}if (i > 0) len = buf[1];if (i > 1) len = len << 8 | buf[2];if (i > 2) len = len << 8 | buf[3];if (i > 3) len = len << 8 | buf[4];}return len;}int getTLVLengthSize(byte[] buf){if (buf[0] < 0x80)return 1;else if (buf[0] > 0x80)return 1 + buf[0] - 0x80;else if (buf[0] == 0x80){}throw new NotSupportedException();}int getTLVSize(TLV tlv){return 1 + getTLVLengthSize(_length) + getTLVDataSize(_length);}}class BooleanTLV : TLV{private bool b;public BooleanTLV(byte[] buf) : base(buf){b = Data[0] != 0;}public bool Value { get { return b;  } }}class ObjectTLV : TLV{private uint[] identifer;public ObjectTLV(byte[] buf) : base(buf){byte[] data = Data;List<uint> r = new List<uint>();r.Add((uint)data[0] / 40);r.Add((uint)data[0] % 40);int i = 1;uint m = 0;while (i < data.Length){m = (uint)((uint)(m << 7) | (uint)(data[i] & 0x7f));if ((data[i] & 0x80) == 0){r.Add(m);m = 0;}i++;}identifer = r.ToArray();}public uint[] Identifer { get { return identifer;  } }}class PrintableStringTLV : TLV{string s = "";public PrintableStringTLV(byte[] buf) : base(buf){for (int i=0; i<Data.Length; i++){s += (char)Data[i];}}public string GetPrintableString(){return s;}}class OctetStringTLV : TLV{public OctetStringTLV(byte[] buf) : base(buf){}public byte[] Bytes { get { return Data;  } }}class IntegerTLV : TLV{private BigInteger _intValue;public IntegerTLV(byte[] buf) :  base(buf){
//            byte[] t = new byte[Data.Length];//           Array.Copy(Data, t, Data.Length);//         Array.Reverse(t);_intValue = new BigInteger(Data, true, true);}public BigInteger IntValue {  get { return _intValue;  } }public byte[] ByteValue { get { return _intValue.ToByteArray(); } }}class NullTLV : TLV{public NullTLV(byte[] buf) : base(buf){}}class UTCTimeTLV : TLV{private DateTime date;public UTCTimeTLV(byte[] buf) : base(buf){string s = "";for (int i=0; i<Data.Length; i++){s += (char) (Data[i]);}date = DateTime.ParseExact(s, "yyMMddHHmmssZ", null, DateTimeStyles.AdjustToUniversal);}public DateTime Date { get { return date;  } }}class BitStringTLV : TLV{public BitStringTLV(byte[] buf) : base(buf){}public byte[] ValidData() {byte fill = Data[0];if (fill != 0){throw new NotImplementedException();}return Bytes.SubBytes(Data, 1);}}class ExtensionsTLV : TLV{private SequenceTLV seq;public ExtensionsTLV(byte[] buf) : base(buf){seq = new SequenceTLV(Data);}public SequenceTLV Sequence { get { return seq; } }}class SequenceTLV : TLV{protected TLV[] children;public SequenceTLV(byte[] buf) : base(buf){List<TLV> tlvs = new List<TLV>();int i = 0;while (i < Data.Length){byte[] bs = Bytes.SubBytes(Data, i);TLV tlv = null;if ((byte)TLVType.Boolean == Data[i]){tlv = new BooleanTLV(bs);}else if ((byte)TLVType.Integer ==  Data[i]){tlv = new IntegerTLV(bs);}else if ((byte) TLVType.OctetString == Data[i]){tlv = new OctetStringTLV(bs);}else if ((byte) TLVType.PrintableString == Data[i]){tlv = new PrintableStringTLV(bs);}else if ((byte) TLVType.Version == Data[i]){tlv = new VersionTLV(bs);}else if ((byte)TLVType.Sequence == Data[i]){tlv = new SequenceTLV(bs);}else if ((byte)TLVType.Object == Data[i]){tlv = new ObjectTLV(bs);}else if ((byte)TLVType.Null == Data[i]){tlv = new NullTLV(bs);}else if ((byte)TLVType.Set == Data[i]){tlv = new SetTLV(bs);}else if ((byte)TLVType.UTCTime == Data[i]){tlv = new UTCTimeTLV(bs);}else if ((byte)TLVType.BitString == Data[i]){tlv = new BitStringTLV(bs);}else if ((byte)TLVType.Extensions == Data[i]){tlv = new ExtensionsTLV(bs);}else{throw new NotSupportedException();}if (tlv != null)tlvs.Add(tlv);i += tlv.Size;}children = tlvs.ToArray();}public TLV[] Children { get { return children; } }}class SetTLV : SequenceTLV{public SetTLV(byte[] buf) :  base(buf){}}class VersionTLV : TLV{private IntegerTLV ver;public VersionTLV(byte[] buf) : base(buf){ver = new IntegerTLV(Data);}public string Version { get { return ver.IntValue.ToString(); } }}}

对证书字段进行显示:

数字证书验签代码:

        private byte[] RSADecrypt(BigInteger? PublicKey){if (PublicKey == null) // 如果是自签名证书,不需要传入上级公钥,传入null{PublicKey = _tbsCertificate.SubjectPublicKeyInfo.Modules;  // 取自己的公钥}BigInteger exponent = _tbsCertificate.SubjectPublicKeyInfo.Exponent;BigInteger msg = new BigInteger(_signatureValue.ValidData(), true, true);BigInteger value = BigInteger.ModPow(msg, exponent, PublicKey.Value);// return value.ToByteArray(false, true); ?? why miss 0// fix code For ==> BigInteger.ToByteArray(false, true) byte[] t = new byte[value.GetByteCount() + 1];Array.Copy(value.ToByteArray(false, true), 0, t, 1, t.Length - 1);return t;}private byte[] RSA_PKCS1_PADDING(byte[] buf){const int BT = 1;int PS;if (BT == 0)PS = 0;else if (BT == 1)PS = 0xFF;elsePS = new Random().Next(1, 255);if (buf[0] != 0 && buf[1] != BT)throw new Exception();int p = 2;while (p < buf.Length){if (buf[p++] == 0)break;}int n = buf.Length - p;byte[] r = new byte[n];Array.Copy(buf, p, r, 0,  r.Length);return r;}public bool Verify(BigInteger? PublicKey){// RSA PublicKey Decryptbyte[] decrypt = RSADecrypt(PublicKey);// RDA Paddingbyte[] values = RSA_PKCS1_PADDING(decrypt);SequenceTLV tlvs = new SequenceTLV(values);OctetStringTLV otlv = (OctetStringTLV)tlvs.Children[1];byte[] result = otlv.Bytes;// SHA-256 byte[] hash = SHA256Managed.Create().ComputeHash(msg);// compare hash And valuesif (hash.Length != result.Length)return false;for (int i = 0; i < result.Length; i++){if (result[i] != hash[i]){return false;}}return true;}

对于自签名证书,利用自己的公钥进行验签

X.509证书解析和验签相关推荐

  1. X.509证书解析程序(C++版)

    这个解析程序使用C++写成,更多详细内容可参考GitHub项目. X.509证书结构 Certificate ::= SEQUENCE {tbsCertificate TBSCertificate, ...

  2. php 生成证书 签名及验签

    http://www.ruanyifeng.com/blog/2011/08/what_is_a_digital_signature.html 立即拥有一个新博 客 一.公钥加密 假设一下,我找了两个 ...

  3. 数字证书应用综合揭秘(包括证书生成、加密、解密、签名、验签)

    引言 数字证书是一个经证书授权中心数字签名的包含公开密钥拥有者信息以及公开密钥的文件.为现实网络安全化标准如今大部分的 B2B.B2C.P2P.O2O 等商业网站含有重要企业资料个人资料的信息资信网站 ...

  4. IdentityServer4之JWT签名(RSA加密证书)及验签

    一.前言 在IdentityServer4中有两种令牌,一个是JWT和Reference Token,在IDS4中默认用的是JWT,那么这两者有什么区别呢? 二.JWT与Reference Token ...

  5. 微信支付API v3签名与验签-APP支付问题

    目录 使用API v3微信支付遇到的问题: 1.微信请求客户端配置 2.生成预付款订单 3.拼接字符串使用API v3签名 4.微信支付成功后通知 使用API v3微信支付遇到的问题: 1.jdk版本 ...

  6. Java 解析CA证书 对数据进行签名和验签

    Java 解析CA证书 对数据进行签名和验签 话不多说直接上代码(pfx证书) pom依赖 <dependency><groupId>org.apache.commons< ...

  7. 【可食用】KeyTool生成KeyStore,证书、公钥、私钥文档JAVA生成,JAVA实现ECC签名验签

    KeyTool生成KeyStore,证书.公钥.私钥文档JAVA生成,JAVA实现ECC签名验签 一.首先我们可以写个工具类生成密钥对.证书.公钥.私钥文本 jksAndCerGenerator.ja ...

  8. java证书加签_证书加签、验签、加密、解密Demo

    package sslSocket; import javax.crypto.Cipher; import java.io.FileInputStream; import java.security. ...

  9. 网络--keytool自签名SSL证书(免费)以及私钥签名、公钥验签

    本文主要介绍keytool自签名SSL证书(免费)以及私钥签名.公钥验签流程,点击查看keytool CA签名SSL证书(收费) 最近给银行做一个系统,虽说是给行内使用的,但是系统要同时支持内外网方式 ...

最新文章

  1. Oracle数据库导入导出命令!
  2. 翻译 | CSS网格(CSS Grid)布局入门
  3. mysql对哪些字符敏感_MySQL对大小写敏感一些总结
  4. Cocos2d JS 之消灭星星(九) 处理星星类之——移动和消灭星星
  5. redis 4.0.9 centos7 双机集群安装
  6. Maven项目配置、检出、运行
  7. 计算机存储单位字的英语,计算机存储基本单位,位、字节、字以及KB、MB和GB怎么换算?...
  8. Struts2学习笔记(九) 拦截器(Interceptor)(下)
  9. 在矩池云上Hugging Face使用清华源
  10. 希望相对路径关于background-image:url()在样式表里设置后有不管用的办法
  11. visio英文版下载与安装教程
  12. 麒麟系统安装打印机共享_银河麒麟 惠普打印机驱动怎么安装
  13. Ubuntu Screen recorder tool - Simple Screen Recorder
  14. 实现Ubuntu与Windows之间的复制粘贴
  15. 超越MRT无数倍的MODIS在线拼接AppEERAS
  16. 学计算机应用专业去当兵有前途么,大学生以哪个专业入伍,发展潜力大?
  17. JSP第四篇【EL表达式介绍、获取各类数据、11个内置对象、执行运算、回显数据、自定义函数、fn方法库】(修订版)...
  18. 【Linux-Windows】猫、路由器、交换机
  19. 判断字符串是不是回文
  20. python爬虫(19)爬取论坛网站——网络上常见的gif动态图

热门文章

  1. 如何来理解当前中国的房地产市场形势?
  2. 自建Kubernetes的LoadBalancer类型服务方案-MetalLB
  3. Unity的Gizmos画线
  4. 教你如何制作一个简单的学生网页
  5. 虚拟化存储的方法有哪几种
  6. xctf攻防世界 CRYPTO高手进阶区 工控安全取证
  7. Hierarchical Contextualized Representation for Named Entity Recognition
  8. webstorm全局搜索搜不到内容
  9. DHU 9 长整数加法运算
  10. 前端小风车 HTML,CSS,Javascript