使用C# CertEnroll库为自签名证书添加IP备用名称的问题
问题:使用C# CertEnroll库添加IP地址型备用主题名称失败
在使用C#的CertEnroll库生成自签名证书时,添加DNS、URL类型的备用主题名称都能正常工作,但添加IP地址时会抛出**“值不在预期范围内”**的异常。
相关代码如下:
CX509CertificateRequestCertificate certificate = new(); ... // Add alternate names CX509ExtensionAlternativeNamesClass alternateNames = new(); CAlternativeNamesClass cAlternativeNames = new(); foreach (CertificateAlias alias in settings.Aliases) { CAlternativeNameClass cAlternativeName = new(); // 测试时alias.Name为"100.120.140.160" cAlternativeName.InitializeFromString(alias.Type.ToAlternativeNameType(), alias.Name); cAlternativeNames.Add(cAlternativeName); } alternateNames.InitializeEncode(cAlternativeNames); certificate.X509Extensions.Add(alternateNames as CX509Extension); certificate.Encode(); ...
settings.Aliases是存储目标备用名称的列表,CertificateAlias仅包含备用名称类型(通过枚举映射)和名称本身。
尝试过的错误方法
直接编码IP字符串为Base64传入
InitializeFromRawData:cAlternativeName.InitializeFromRawData(AlternativeNameType.XCN_CERT_ALT_NAME_IP_ADDRESS, EncodingType.XCN_CRYPT_STRING_BASE64, Convert.ToBase64String(Encoding.UTF8.GetBytes("100.120.140.160")));结果:证书中IP地址显示为Base64格式,不符合预期。
直接传入IP字符串:
cAlternativeName.InitializeFromRawData(AlternativeNameType.XCN_CERT_ALT_NAME_IP_ADDRESS, EncodingType.XCN_CRYPT_STRING_BASE64, "100.120.140.160");结果:抛出**“无效数据”**异常。
解决方案
需要使用InitializeFromRawData方法,且要将IP地址拆分为单个字节(而非直接编码字符串),再转换为Base64格式传入。具体代码如下:
List<byte> bytes = new(); string[] octets = alias.Name.Split('.'); for (int i = 0; i < octets.Length; i++) bytes.Add(byte.Parse(octets[i])); cAlternativeName.InitializeFromRawData(AlternativeNameType.XCN_CERT_ALT_NAME_IP_ADDRESS, EncodingType.XCN_CRYPT_STRING_BASE64, Convert.ToBase64String(bytes.ToArray()));
原理:IP地址型备用名称需要以原始字节数组的形式存储(每个分段对应一个字节),而非字符串的UTF-8编码,因此需要先将IP的每个分段解析为字节,再转换为Base64后传入。
内容的提问来源于stack exchange,提问作者Korz
相关产品推荐
相关产品推荐

