You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在C#中使用System.Formats.Asn1.AsnReader读取公钥的指数和模数

如何在C#中使用System.Formats.Asn1.AsnReader读取公钥的指数和模数

嘿,看得出来你已经在使用System.Formats.Asn1.AsnReader解析DER证书的路上走了一大段啦!既然已经成功初始化了读取器、读到了tsb部分,甚至摸到了公钥信息里的算法环节,那接下来拿到RSA公钥的指数和模数其实就差最后几步,我来给你详细说说:

首先先回顾下你已经完成的关键操作:

  • 成功初始化了AsnReader:
    AsnReader readerAll = new AsnReader(new ReadOnlyMemory<byte>(certificateDER), AsnEncodingRules.DER);
    
  • 顺利读取到了tsb区域的内容,并且进到了公钥信息(SubjectPublicKeyInfo)的算法部分

接下来的核心逻辑是:公钥信息里的公钥内容是以BIT STRING的形式存储的,里面包裹着一个RSA公钥的SEQUENCE结构,这个SEQUENCE就包含了我们要的模数(n)和指数(e)。具体步骤如下:

  1. 读取公钥的BIT STRING
    在你处理完公钥信息里的算法标识符之后,接下来要读取的就是公钥的BIT STRING数据,这个数据里就是我们需要解析的RSA公钥内容:

    // 读取BIT STRING,unusedBits一般为0(因为公钥内容是整字节的)
    ReadOnlyMemory<byte> publicKeyBitString = readerAll.ReadBitString(out int unusedBits);
    
  2. 创建新的AsnReader解析公钥内容
    因为BIT STRING里的内容是一个独立的ASN.1 SEQUENCE,所以我们需要用这个内容创建一个新的AsnReader来单独解析:

    AsnReader publicKeyReader = new AsnReader(publicKeyBitString, AsnEncodingRules.DER);
    
  3. 读取模数和指数
    RSA公钥的SEQUENCE里包含两个INTEGER类型的元素,第一个是模数(n),第二个是指数(e),我们可以依次读取它们:

    // 读取公钥的SEQUENCE,用using确保资源正确释放
    using (AsnReader rsaPublicKeyReader = publicKeyReader.ReadSequence())
    {
        // 读取模数(n),转换为BigInteger方便后续使用
        ReadOnlyMemory<byte> modulusBytes = rsaPublicKeyReader.ReadIntegerBytes();
        BigInteger modulus = new BigInteger(modulusBytes.Span, isUnsigned: true, isBigEndian: true);
        
        // 读取指数(e),同样转换为BigInteger
        ReadOnlyMemory<byte> exponentBytes = rsaPublicKeyReader.ReadIntegerBytes();
        BigInteger exponent = new BigInteger(exponentBytes.Span, isUnsigned: true, isBigEndian: true);
        
        // 到这里你就成功拿到了模数和指数,可以根据业务需求使用啦
    }
    

一些小提醒:

  • 全程要保持编码规则为AsnEncodingRules.DER,因为X.509证书的ASN.1编码都是遵循DER规范的
  • 如果你的公钥不是RSA类型(比如ECDSA),那公钥的结构会不一样,但从你提到的“指数和模数”来看,应该是RSA公钥没问题
  • 读取整数的时候,ReadIntegerBytes返回的是原始的大端字节序无符号整数,用BigInteger的对应构造方法可以正确解析

备注:内容来源于stack exchange,提问作者Tamil Shenbaga Selvi

火山引擎 最新活动