/// <summary>
        /// Displays an X.509 certificate dump.
        /// </summary>
        /// <returns>Formatted string.</returns>
        public static String Format(this X509Certificate2 cert)
        {
            if (cert == null)
            {
                return(String.Empty);
            }

            var    blob     = new SignedContentBlob(cert.RawData, ContentBlobType.SignedBlob);
            String sigValue = AsnFormatter.BinaryToString(blob.Signature.Value.Reverse().ToArray(), EncodingType.HexAddress)
                              .Replace(Environment.NewLine, Environment.NewLine + "    ");
            var sb = new StringBuilder();


            sb.Append($@"X509 Certificate:
Version: {cert.Version} (0x{cert.Version - 1:x})
Serial Number: {cert.SerialNumber}

{blob.SignatureAlgorithm}
Issuer:
    {cert.IssuerName.FormatReverse(true).Replace(Environment.NewLine, Environment.NewLine + "    ")}
  Name Hash(md5)    : {getNameHash(cert.IssuerName, MD5.Create())}
  Name Hash(sha1)   : {getNameHash(cert.IssuerName, SHA1.Create())}
  Name Hash(sha256) : {getNameHash(cert.IssuerName, SHA256.Create())}

Valid From: {cert.NotBefore}
Valid To  : {cert.NotAfter}

Subject:
    {cert.SubjectName.FormatReverse(true).Replace(Environment.NewLine, Environment.NewLine + "    ")}
  Name Hash(md5)    : {getNameHash(cert.SubjectName, MD5.Create())}
  Name Hash(sha1)   : {getNameHash(cert.SubjectName, SHA1.Create())}
  Name Hash(sha256) : {getNameHash(cert.SubjectName, SHA256.Create())}

{cert.PublicKey.Format().TrimEnd()}

Certificate Extensions: {cert.Extensions.Count}
{cert.Extensions.Format()}

{blob.SignatureAlgorithm.ToString().TrimEnd()}
Signature: UnusedBits={blob.Signature.UnusedBits}
    {sigValue}
");
            sb.AppendLine(cert.Issuer.Equals(cert.Subject, StringComparison.InvariantCultureIgnoreCase)
                ? "Root Certificate: Subject matches Issuer"
                : "Non-root Certificate");
            sb.AppendLine($"Key Id Hash(sha1)       : {getHashData(cert.PublicKey.Encode(), SHA1.Create())}");
            sb.AppendLine($"Key Id Hash(rfc-md5)    : {getHashData(cert.PublicKey.EncodedKeyValue.RawData, MD5.Create())}");
            sb.AppendLine($"Key Id Hash(rfc-sha1)   : {getHashData(cert.PublicKey.EncodedKeyValue.RawData, SHA1.Create())}");
            sb.AppendLine($"Key Id Hash(rfc-sha256) : {getHashData(cert.PublicKey.EncodedKeyValue.RawData, SHA256.Create())}");
            sb.AppendLine($"Key Id Hash(pin-sha256-b64) : {getKeyPinHash(cert.PublicKey, SHA256.Create())}");
            sb.AppendLine($"Key Id Hash(pin-sha256-hex) : {getHashData(cert.PublicKey.Encode(), SHA256.Create())}");
            sb.AppendLine($"Cert Hash(md5)    : {getCertHash(cert, MD5.Create())}");
            sb.AppendLine($"Cert Hash(sha1)   : {getCertHash(cert, SHA1.Create())}");
            sb.AppendLine($"Cert Hash(sha256) : {getCertHash(cert, SHA256.Create())}");
            sb.AppendLine($"Signature Hash    : {getHashData(blob.GetRawSignature(), SHA1.Create())}");
            return(sb.ToString());
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Verifies signature of a signed blob by using specified public key.
        /// </summary>
        /// <param name="blob"></param>
        /// <param name="publicKey"></param>
        /// <returns></returns>
        /// <remarks>
        /// This method is suitable to validate certificate signing requests (CSR) or other data
        /// when signing key pair exist outside of X.509 certificate object.
        /// </remarks>
        public static Boolean VerifyData(SignedContentBlob blob, PublicKey publicKey)
        {
            if (blob == null)
            {
                throw new ArgumentNullException(nameof(blob));
            }
            if (publicKey == null)
            {
                throw new ArgumentNullException(nameof(publicKey));
            }

            if (blob.BlobType != ContentBlobType.SignedBlob)
            {
                throw new InvalidOperationException("The blob is not signed.");
            }

            using (var signerInfo = new MessageSigner()) {
                signerInfo.acquirePublicKey(publicKey);
                signerInfo.getConfiguration(blob.SignatureAlgorithm.RawData);
                return(signerInfo.VerifyData(blob.ToBeSignedData, blob.GetRawSignature()));
            }
        }