gpt4 book ai didi

c# - 计算公钥密码 (.Net)

转载 作者:太空宇宙 更新时间:2023-11-03 21:08:35 25 4
gpt4 key购买 nike

我想知道如何计算X509证书的公钥密码?

例如。我通过网络请求获得了证书

        var cert = (httpRequest as HttpWebRequest).ServicePoint.Certificate;
X509Certificate2 cert2 = new X509Certificate2(cert);

我不确定此后要做什么,因为我需要主题公钥信息(对其进行哈希处理)但我无法在 X509Certificate2 类中找到它或不确定如何构造它。我可以通过 GetKeyInfo() 方法获取指数和模数,这似乎是 SPKI 的核心。

我确信有一种简单的方法可以做到这一点,但任何帮助都会很棒!

谢谢

最佳答案

精简版

辅助方法:

String publicKeyPinningHash = certificate.GetPublicKeyPinningHash();

String s = String.Format("Public-Key-Pins: pin-sha256=\"{0}\";
max-age=31536000", publicKeyHash);

Facebook.com 吐出的内容:

Public-Key-Pins: pin-sha256="hUIG87ch71EZQYhZBEkq2VKBLjhussUw7nR8wyuY7rY="; max-age=31536000

功能性 .NET fiddle

https://dotnetfiddle.net/F9t6IQ

背景

如您所见,.NET Framework 无法操作 X509Certificate .

X.509 证书使用 ASN.1 的 DER 风格进行编码。 .NET Framework 无法操纵 AsnEcodedData .

这意味着我们需要滚动自己的代码来计算 X.509 证书的 PublicKeyPinning 哈希:

static String GetPublicKeyPinningHash(X509Certificate2 x509Cert)
{
//Public Domain: No attribution required
//Get the SubjectPublicKeyInfo member of the certificate
Byte[] subjectPublicKeyInfo = GetSubjectPublicKeyInfoRaw(x509Cert);

//Take the SHA2-256 hash of the DER ASN.1 encoded value
Byte[] digest;
using (var sha2 = new SHA256Managed())
{
digest = sha2.ComputeHash(subjectPublicKeyInfo);
}

//Convert hash to base64
String hash = Convert.ToBase64String(digest);

return hash;
}

这段代码建立在 .NET 也没有提供的底层函数之上,以获取原始的 SubjectPublickeyInfo 字节:

    static Byte[] GetSubjectPublicKeyInfoRaw(X509Certificate2 x509Cert)
{
//Public Domain: No attribution required
Byte[] rawCert = x509Cert.GetRawCertData();

/*
Certificate is, by definition:

Certificate ::= SEQUENCE {
tbsCertificate TBSCertificate,
signatureAlgorithm AlgorithmIdentifier,
signatureValue BIT STRING
}

TBSCertificate ::= SEQUENCE {
version [0] EXPLICIT Version DEFAULT v1,
serialNumber CertificateSerialNumber,
signature AlgorithmIdentifier,
issuer Name,
validity Validity,
subject Name,
subjectPublicKeyInfo SubjectPublicKeyInfo,
issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, -- If present, version MUST be v2 or v3
subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, -- If present, version MUST be v2 or v3
extensions [3] EXPLICIT Extensions OPTIONAL -- If present, version MUST be v3
}

So we walk to ASN.1 DER tree in order to drill down to the SubjectPublicKeyInfo item
*/
Byte[] list = AsnNext(ref rawCert, true); //unwrap certificate sequence
Byte[] tbsCertificate = AsnNext(ref list, false); //get next item; which is tbsCertificate
list = AsnNext(ref tbsCertificate, true); //unwap tbsCertificate sequence

Byte[] version = AsnNext(ref list, false); //tbsCertificate.Version
Byte[] serialNumber = AsnNext(ref list, false); //tbsCertificate.SerialNumber
Byte[] signature = AsnNext(ref list, false); //tbsCertificate.Signature
Byte[] issuer = AsnNext(ref list, false); //tbsCertificate.Issuer
Byte[] validity = AsnNext(ref list, false); //tbsCertificate.Validity
Byte[] subject = AsnNext(ref list, false); //tbsCertificate.Subject
Byte[] subjectPublicKeyInfo = AsnNext(ref list, false); //tbsCertificate.SubjectPublicKeyInfo

return subjectPublicKeyInfo;
}

它建立在较低级别的函数之上,用于解析使用 ASN.1 的 DER 风格编码的 ASN.1 编码数据:

    static Byte[] AsnNext(ref Byte[] buffer, Boolean unwrap)
{
//Public Domain: No attribution required
Byte[] result;

if (buffer.Length < 2)
{
result = buffer;
buffer = new Byte[0];
return result;
}

int index = 0;
Byte entityType = buffer[index];
index += 1;

int length = buffer[index];
index += 1;

int lengthBytes = 1;
if (length >= 0x80)
{
lengthBytes = length & 0x0F; //low nibble is number of length bytes to follow
length = 0;

for (int i = 0; i < lengthBytes; i++)
{
length = (length << 8) + (int)buffer[2 + i];
index += 1;
}
lengthBytes++;
}

int copyStart;
int copyLength;
if (unwrap)
{
copyStart = 1 + lengthBytes;
copyLength = length;
}
else
{
copyStart = 0;
copyLength = 1 + lengthBytes + length;
}
result = new Byte[copyLength];
Array.Copy(buffer, copyStart, result, 0, copyLength);

Byte[] remaining = new Byte[buffer.Length - (copyStart+copyLength)];
if (remaining.Length > 0)
Array.Copy(buffer, copyStart + copyLength, remaining, 0, remaining.Length);
buffer = remaining;

return result;
}

关于c# - 计算公钥密码 (.Net),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39441425/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com