Пример #1
0
        public void GetAsymmetricAlgorithm()
        {
            X509AsymmetricSecurityKey key = new X509AsymmetricSecurityKey(cert);
            string name             = EncryptedXml.XmlEncRSA15Url;
            AsymmetricAlgorithm alg = key.GetAsymmetricAlgorithm(name, false);

            Assert.IsNotNull(alg, "#1");
            alg = key.GetAsymmetricAlgorithm(name, true);
            Assert.IsNotNull(alg, "#2");

            key = new X509AsymmetricSecurityKey(cert2);
            alg = key.GetAsymmetricAlgorithm(name, false);
            Assert.IsNotNull(alg, "#3");
        }
Пример #2
0
        public byte[] SignWithCertificate(string message, X509Certificate2 certificate)
        {
            if (certificate.PublicKey.Key.KeySize < ClientAssertionCertificate.MinKeySizeInBits)
            {
                throw new ArgumentOutOfRangeException("rawData",
                                                      string.Format(CultureInfo.InvariantCulture, AdalErrorMessage.CertificateKeySizeTooSmallTemplate, ClientAssertionCertificate.MinKeySizeInBits));
            }

            X509AsymmetricSecurityKey x509Key = new X509AsymmetricSecurityKey(certificate);
            RSACryptoServiceProvider  rsa     = x509Key.GetAsymmetricAlgorithm(SecurityAlgorithms.RsaSha256Signature, true) as RSACryptoServiceProvider;

            RSACryptoServiceProvider newRsa = null;

            try
            {
                newRsa = GetCryptoProviderForSha256(rsa);
                using (SHA256Cng sha = new SHA256Cng())
                {
                    return(newRsa.SignData(Encoding.UTF8.GetBytes(message), sha));
                }
            }
            finally
            {
                if (newRsa != null && !ReferenceEquals(rsa, newRsa))
                {
                    newRsa.Dispose();
                }
            }
        }
        public byte[] SignWithCertificate(string message, X509Certificate2 certificate)
        {
            if (certificate.PublicKey.Key.KeySize < ClientAssertionCertificate.MinKeySizeInBits)
            {
                throw new ArgumentOutOfRangeException(nameof(certificate),
                                                      string.Format(CultureInfo.InvariantCulture, AdalErrorMessage.CertificateKeySizeTooSmallTemplate,
                                                                    ClientAssertionCertificate.MinKeySizeInBits));
            }

            byte[] messageBytes = Encoding.UTF8.GetBytes(message);
            var    x509Key      = new X509AsymmetricSecurityKey(certificate);

            RSA rsa = x509Key.GetAsymmetricAlgorithm(SecurityAlgorithms.RsaSha256Signature, true) as RSA;

            RSACryptoServiceProvider newRsa = null;

            try
            {
                if (rsa is RSACryptoServiceProvider cspRsa)
                {
                    // For .NET 4.6 and below we get the old RSACryptoServiceProvider implementation as the default.
                    // Try and get an instance of RSACryptoServiceProvider which supports SHA256
                    newRsa = GetCryptoProviderForSha256(cspRsa);

                    using (var sha = new SHA256Cng())
                    {
                        return(newRsa.SignData(messageBytes, sha));
                    }
                }
                else
                {
                    CngKey key = GetCngPrivateKey(certificate);
                    using (RSACng rsaCng = new RSACng(key))
                    {
                        rsaCng.SignatureHashAlgorithm = CngAlgorithm.Sha256;
                        return(rsaCng.SignData(messageBytes));
                    }
                }
            }
            finally
            {
                // We only want to dispose of the 'newRsa' instance if it is a *different instance*
                // from the original one that was used to create it.
                if (newRsa != null && !ReferenceEquals(rsa, newRsa))
                {
                    newRsa.Dispose();
                }
            }
        }
        /// <inheritdoc />
        public byte[] SignWithCertificate(string message, X509Certificate2 certificate)
        {
            if (certificate.PublicKey.Key.KeySize < ClientAssertionCertificateWrapper.MinKeySizeInBits)
            {
                throw new ArgumentOutOfRangeException(nameof(certificate),
                                                      string.Format(CultureInfo.InvariantCulture, MsalErrorMessage.CertificateKeySizeTooSmallTemplate,
                                                                    ClientAssertionCertificateWrapper.MinKeySizeInBits));
            }

            byte[] messageBytes = Encoding.UTF8.GetBytes(message);
            var    x509Key      = new X509AsymmetricSecurityKey(certificate);

            RSA rsa = x509Key.GetAsymmetricAlgorithm(SecurityAlgorithms.RsaSha256Signature, true) as RSA;

            RSACryptoServiceProvider newRsa = null;

            try
            {
                if (rsa is RSACryptoServiceProvider cspRsa)
                {
                    // For .NET 4.6 and below we get the old RSACryptoServiceProvider implementation as the default.
                    // Try and get an instance of RSACryptoServiceProvider which supports SHA256
                    newRsa = GetCryptoProviderForSha256(cspRsa);
                }
                else
                {
                    // For .NET Framework 4.7 and onwards the RSACng implementation is the default.
                    // Since we're targeting .NET Framework 4.5, we cannot actually use this type as it was
                    // only introduced with .NET Framework 4.6.
                    // Instead we try and create an RSACryptoServiceProvider based on the private key from the
                    // certificate.
                    newRsa = GetCryptoProviderForSha256(certificate);
                }

                using (var sha = new SHA256Cng())
                {
                    return(newRsa.SignData(messageBytes, sha));
                }
            }
            finally
            {
                // We only want to dispose of the 'newRsa' instance if it is a *different instance*
                // from the original one that was used to create it.
                if (newRsa != null && !ReferenceEquals(rsa, newRsa))
                {
                    newRsa.Dispose();
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Validate whether the unsigned value is same as signed value
        /// </summary>
        /// <param name="uval">
        /// The raw input of the string signed using the key
        /// </param>
        /// <param name="sval">
        /// The signature of the string
        /// </param>
        /// <param name="certthumb">
        /// The thumbprint of cert used to encrypt token
        /// </param>
        /// <returns>
        /// True if same, false otherwise.
        /// </returns>
        private static bool ValidateSig(byte[] uval, byte[] sval, byte[] certthumb)
        {
            try {
                bool ret = false;

                X509Certificate2[] certx509     = GetEncodingCert();
                string             certthumbhex = string.Empty;

                // Get the hexadecimail representation of the certthumbprint
                for (int i = 0; i < certthumb.Length; i++)
                {
                    certthumbhex += certthumb[i].ToString("X2");
                }

                for (int c = 0; c < certx509.Length; c++)
                {
                    // Skip any cert that does not have the same thumbprint as token
                    if (certx509[c].Thumbprint.ToLower() != certthumbhex.ToLower())
                    {
                        continue;
                    }
                    X509SecurityToken tok = new X509SecurityToken(certx509[c]);
                    if (tok == null)
                    {
                        return(false);
                    }
                    for (int i = 0; i < tok.SecurityKeys.Count; i++)
                    {
                        X509AsymmetricSecurityKey key = tok.SecurityKeys[i] as X509AsymmetricSecurityKey;
                        RSACryptoServiceProvider  rsa = key.GetAsymmetricAlgorithm(SecurityAlgorithms.RsaSha256Signature, false) as RSACryptoServiceProvider;

                        if (rsa == null)
                        {
                            continue;
                        }
                        ret = rsa.VerifyData(uval, hash, sval);
                        if (ret == true)
                        {
                            return(ret);
                        }
                    }
                }
                return(ret);
            } catch (CryptographicException e) {
                Console.WriteLine(e.ToStringDescriptive());
                return(false);
            }
        }
        /// <summary>
        /// Sign the data with the X509Certificate
        /// </summary>
        /// <param name="signingCertificate">Signing certificate.</param>
        /// <param name="data">Data to be signed.</param>
        /// <returns>RSA SHA 256 Signature</returns>
        public static byte[] SignData(X509Certificate2 signingCertificate, string data)
        {
            X509AsymmetricSecurityKey securityKey = new X509AsymmetricSecurityKey(signingCertificate);

            RSACryptoServiceProvider rsa =
                securityKey.GetAsymmetricAlgorithm("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", true)
                as RSACryptoServiceProvider;

            if (!signingCertificate.HasPrivateKey)
            {
                throw new ArgumentException(string.Format(
                                                "Private key is not found in the certificate: {0}",
                                                signingCertificate.Subject));
            }

            if (rsa != null)
            {
                rsa.FromXmlString(signingCertificate.PrivateKey.ToXmlString(true));

                if (rsa.CspKeyContainerInfo.ProviderType != 24)
                {
                    System.Security.Cryptography.CspParameters cspParameters =
                        new System.Security.Cryptography.CspParameters
                    {
                        ProviderType     = 24,
                        KeyContainerName = rsa.CspKeyContainerInfo.KeyContainerName,
                        KeyNumber        = (int)rsa.CspKeyContainerInfo.KeyNumber
                    };

                    if (rsa.CspKeyContainerInfo.MachineKeyStore)
                    {
                        cspParameters.Flags = CspProviderFlags.UseMachineKeyStore;
                    }

                    rsa = new System.Security.Cryptography.RSACryptoServiceProvider(cspParameters);
                }
            }

            HashAlgorithm hashAlgo = System.Security.Cryptography.SHA256.Create();

            byte[] signatureInBytes = rsa.SignData(Encoding.UTF8.GetBytes(data), hashAlgo);

            return(signatureInBytes);
        }
        public static byte[] SignWithCertificate(string message, X509Certificate2 x509Certificate)
        {
            X509AsymmetricSecurityKey x509Key = new X509AsymmetricSecurityKey(x509Certificate);
            RSACryptoServiceProvider  rsa     = x509Key.GetAsymmetricAlgorithm(SecurityAlgorithms.RsaSha256Signature, true) as RSACryptoServiceProvider;

            RSACryptoServiceProvider newRsa = null;

            try
            {
                newRsa = GetCryptoProviderForSha256(rsa);
                using (SHA256 sha = SHA256.Create())
                {
                    return(newRsa.SignData(Encoding.UTF8.GetBytes(message), sha));
                }
            }
            finally
            {
                if (newRsa != null && !object.ReferenceEquals(rsa, newRsa))
                {
                    newRsa.Dispose();
                }
            }
        }
Пример #8
0
        [Category("NotDotNet")]          // buggy FormatException occurs instead
        public void GetAsymmetricAlgorithmHMACSHA1()
        {
            X509AsymmetricSecurityKey key = new X509AsymmetricSecurityKey(cert);

            key.GetAsymmetricAlgorithm(SignedXml.XmlDsigHMACSHA1Url, false);
        }
Пример #9
0
 public void GetAsymmetricAlgorithmDSA()
 {
     X509AsymmetricSecurityKey key = new X509AsymmetricSecurityKey(cert);
     AsymmetricAlgorithm       alg = key.GetAsymmetricAlgorithm(SignedXml.XmlDsigDSAUrl, false);
 }
Пример #10
0
        [Category("NotDotNet")]          // buggy FormatException occurs instead
        public void GetAsymmetricAlgorithmNullAlgName()
        {
            X509AsymmetricSecurityKey key = new X509AsymmetricSecurityKey(cert);

            key.GetAsymmetricAlgorithm(null, false);
        }
Пример #11
0
        public void GetAsymmetricAlgorithmWhereNoPrivKey()
        {
            X509AsymmetricSecurityKey key = new X509AsymmetricSecurityKey(cert2);

            key.GetAsymmetricAlgorithm(EncryptedXml.XmlEncRSA15Url, true);
        }
        // Get the access token via straight http post request doing client credential flow
        private async Task <String> GetAppOnlyAccessTokenWithHttpRequest(string resource, string tenantId)
        {
            /**
             * use the tenant specific endpoint for requesting the app-only access token
             */
            string tokenIssueEndpoint = appConfig.TokenIssueingUri.Replace("common", tenantId);

            /**
             * sign the assertion with the private key
             */
            string           certfile = Server.MapPath(appConfig.ClientCertificatePfx);
            X509Certificate2 cert     = new X509Certificate2(
                certfile,
                appConfig.ClientCertificatePfxPassword,
                X509KeyStorageFlags.MachineKeySet);

            /**
             * Example building assertion using Json Tokenhandler.
             * Sort of cheating, but just if someone wonders ... there are always more ways to do something :-)
             */
            Dictionary <string, string> claims = new Dictionary <string, string>()
            {
                { "sub", appConfig.ClientId },
                { "jti", Guid.NewGuid().ToString() },
            };

            JwtSecurityTokenHandler tokenHandler       = new JwtSecurityTokenHandler();
            X509SigningCredentials  signingCredentials = new X509SigningCredentials(cert, SecurityAlgorithms.RsaSha256Signature, SecurityAlgorithms.Sha256Digest);

            JwtSecurityToken selfSignedToken = new JwtSecurityToken(
                appConfig.ClientId,
                tokenIssueEndpoint,
                claims.Select(c => new Claim(c.Key, c.Value)),
                DateTime.UtcNow,
                DateTime.UtcNow.Add(TimeSpan.FromMinutes(15)),
                signingCredentials);

            string signedAssertion = tokenHandler.WriteToken(selfSignedToken);

            //---- End example with Json Tokenhandler... now to the fun part doing it all ourselves ...

            /**
             * Example building assertion from scratch with Crypto APIs
             */
            JObject clientAssertion = new JObject();

            clientAssertion.Add("aud", tokenIssueEndpoint);
            clientAssertion.Add("iss", appConfig.ClientId);
            clientAssertion.Add("sub", appConfig.ClientId);
            clientAssertion.Add("jti", Guid.NewGuid().ToString());
            clientAssertion.Add("nbf", WebConvert.EpocTime(DateTime.UtcNow + TimeSpan.FromMinutes(-5)));
            clientAssertion.Add("exp", WebConvert.EpocTime(DateTime.UtcNow + TimeSpan.FromMinutes(15)));

            string assertionPayload = clientAssertion.ToString(Newtonsoft.Json.Formatting.None);

            X509AsymmetricSecurityKey x509Key = new X509AsymmetricSecurityKey(cert);
            RSACryptoServiceProvider  rsa     = x509Key.GetAsymmetricAlgorithm(SecurityAlgorithms.RsaSha256Signature, true) as RSACryptoServiceProvider;
            RSACryptoServiceProvider  newRsa  = GetCryptoProviderForSha256(rsa);
            SHA256Cng sha = new SHA256Cng();

            JObject header     = new JObject(new JProperty("alg", "RS256"));
            string  thumbprint = WebConvert.Base64UrlEncoded(WebConvert.HexStringToBytes(cert.Thumbprint));

            header.Add(new JProperty("x5t", thumbprint));

            string encodedHeader  = WebConvert.Base64UrlEncoded(header.ToString());
            string encodedPayload = WebConvert.Base64UrlEncoded(assertionPayload);

            string signingInput = String.Concat(encodedHeader, ".", encodedPayload);

            byte[] signature = newRsa.SignData(Encoding.UTF8.GetBytes(signingInput), sha);

            signedAssertion = string.Format("{0}.{1}.{2}",
                                            encodedHeader,
                                            encodedPayload,
                                            WebConvert.Base64UrlEncoded(signature));

            /**
             * build the request payload
             */
            FormUrlEncodedContent tokenRequestForm;

            tokenRequestForm = new FormUrlEncodedContent(
                new[] {
                new KeyValuePair <string, string>("resource", appConfig.ExchangeResourceUri),
                new KeyValuePair <string, string>("client_id", appConfig.ClientId),
                new KeyValuePair <string, string>("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"),
                new KeyValuePair <string, string>("client_assertion", signedAssertion),
                new KeyValuePair <string, string>("grant_type", "client_credentials"),
            }
                );

            /*
             * Do the web request
             */
            HttpClient client = new HttpClient();

            Task <string> requestString  = tokenRequestForm.ReadAsStringAsync();
            StringContent requestContent = new StringContent(requestString.Result);

            requestContent.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
            requestContent.Headers.Add("client-request-id", System.Guid.NewGuid().ToString());
            requestContent.Headers.Add("return-client-request-id", "true");
            requestContent.Headers.Add("UserAgent", "MatthiasLeibmannsAppOnlyAppSampleBeta/0.1");

            HttpResponseMessage response       = client.PostAsync(tokenIssueEndpoint, requestContent).Result;
            JObject             jsonResponse   = JObject.Parse(response.Content.ReadAsStringAsync().Result);
            JsonSerializer      jsonSerializer = new JsonSerializer();

            if (response.IsSuccessStatusCode == true)
            {
                AADClientCredentialSuccessResponse s = (AADClientCredentialSuccessResponse)jsonSerializer.Deserialize(new JTokenReader(jsonResponse), typeof(AADClientCredentialSuccessResponse));
                return(s.access_token);
            }

            AADClientCredentialErrorResponse e = (AADClientCredentialErrorResponse)jsonSerializer.Deserialize(new JTokenReader(jsonResponse), typeof(AADClientCredentialErrorResponse));

            throw new Exception(e.error_description);
        }
Пример #13
0
        private static byte[] GenerateSignerBlock(SignerConfig signerConfig,
                                                  IDictionary <ContentDigestAlgorithm, byte[]> contentDigests)
        {
            var publicKey        = signerConfig.Certificates.PublicKey;
            var encodedPublicKey = EncodePublicKey(publicKey);

            var signedData = new V2SignatureSchemeBlock.SignedData();

            try
            {
                signedData.Certificate = EncodeCertificates(signerConfig.Certificates);
            }
            catch (CryptographicException e)
            {
                throw new CryptographicException("Failed to encode certificates", e);
            }

            var digests = new List <Tuple <int, byte[]> >(1);

            var contentDigestAlgorithm =
                signerConfig.SignatureAlgorithm.ContentDigestAlgorithm;
            var contentDigest = contentDigests[contentDigestAlgorithm];

            if (contentDigest == null)
            {
                throw new Exception(
                          contentDigestAlgorithm + " content digest for " + signerConfig.SignatureAlgorithm
                          + " not computed");
            }

            digests.Add(Tuple.Create(signerConfig.SignatureAlgorithm.Id, contentDigest));
            signedData.Digests = digests;
            var signer = new V2SignatureSchemeBlock.Signer();

            // FORMAT:
            // * length-prefixed sequence of length-prefixed digests:
            //   * uint32: signature algorithm ID
            //   * length-prefixed bytes: digest of contents
            // * length-prefixed sequence of certificates:
            //   * length-prefixed bytes: X.509 certificate (ASN.1 DER encoded).
            // * length-prefixed sequence of length-prefixed additional attributes:
            //   * uint32: ID
            //   * (length - 4) bytes: value
            signer.SignedData = EncodeAsSequenceOfLengthPrefixedElements(new[]
            {
                EncodeAsSequenceOfLengthPrefixedPairsOfIntAndLengthPrefixedBytes(signedData.Digests),
                EncodeAsSequenceOfLengthPrefixedElements(new[] { signedData.Certificate }),
                // additional attributes
                new byte[0],
            });
            signer.PublicKey  = encodedPublicKey;
            signer.Signatures = new List <Tuple <int, byte[]> >(1);
            var signatureAlgorithm = signerConfig.SignatureAlgorithm;

            {
                var    digestAlgorithm = signatureAlgorithm.DigestAlgorithm;
                byte[] signatureBytes;

                var x509Key = new X509AsymmetricSecurityKey(signerConfig.Certificates);

                if (signerConfig.Certificates.PrivateKey is RSACryptoServiceProvider x)
                {
                    if (digestAlgorithm.Oid == DigestAlgorithm.SHA1.Oid)
                    {
                        var rsa = (RSA)x509Key.GetAsymmetricAlgorithm(SecurityAlgorithms.RsaSha1Signature, true);
                        signatureBytes = rsa.SignData(signer.SignedData, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);
                    }
                    else if (digestAlgorithm.Oid == DigestAlgorithm.SHA256.Oid)
                    {
                        var rsa = (RSA)x509Key.GetAsymmetricAlgorithm(SecurityAlgorithms.RsaSha256Signature, true);
                        signatureBytes = rsa.SignData(signer.SignedData, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
                    }
                    else if (digestAlgorithm.Oid == DigestAlgorithm.SHA512.Oid)
                    {
                        var rsa = (RSA)x509Key.GetAsymmetricAlgorithm("http://www.w3.org/2001/04/xmldsig-more#rsa-sha512", true);
                        signatureBytes = rsa.SignData(signer.SignedData, HashAlgorithmName.SHA512, RSASignaturePadding.Pkcs1);
                    }
                    else
                    {
                        throw new CryptographicException($"Failed to sign using {digestAlgorithm.Name} unsupproted digest");
                    }
                }
                else if (signerConfig.Certificates.PrivateKey is DSACryptoServiceProvider dsa)
                {
                    signatureBytes = dsa.SignData(signer.SignedData);
                }
                else
                {
                    throw new CryptographicException("Failed to sign using " + digestAlgorithm.Name);
                }


                switch (publicKey.Key)
                {
                case RSACryptoServiceProvider rsaPub:
                    using (var rsa2 = new RSACryptoServiceProvider())
                        using (var hash = digestAlgorithm.CreateInstance())
                        {
                            rsa2.ImportParameters(rsaPub.ExportParameters(false));
                            if (!rsa2.VerifyData(signer.SignedData, hash, signatureBytes))
                            {
                                throw new CryptographicException("Signature did not verify");
                            }
                        }

                    break;

                case DSACryptoServiceProvider dsaPub:
                    using (var dsa2 = new DSACryptoServiceProvider())
                    {
                        dsa2.ImportParameters(dsaPub.ExportParameters(false));
                        if (!dsa2.VerifyData(signer.SignedData, signatureBytes))
                        {
                            throw new CryptographicException("Signature did not verify");
                        }
                    }

                    break;

                default:
                    throw new CryptographicException(
                              "Failed to verify generated " + digestAlgorithm.Name + " signature using"
                              + " public key from certificate");
                }

                signer.Signatures.Add(Tuple.Create(signatureAlgorithm.Id, signatureBytes));
            }
            // FORMAT:
            // * length-prefixed signed data
            // * length-prefixed sequence of length-prefixed signatures:
            //   * uint32: signature algorithm ID
            //   * length-prefixed bytes: signature of signed data
            // * length-prefixed bytes: public key (X.509 SubjectPublicKeyInfo, ASN.1 DER encoded)
            return(EncodeAsSequenceOfLengthPrefixedElements(
                       new[]
            {
                signer.SignedData,
                EncodeAsSequenceOfLengthPrefixedPairsOfIntAndLengthPrefixedBytes(
                    signer.Signatures),
                signer.PublicKey,
            }));
        }