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"); }
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(); } } }
/// <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(); } } }
[Category("NotDotNet")] // buggy FormatException occurs instead public void GetAsymmetricAlgorithmHMACSHA1() { X509AsymmetricSecurityKey key = new X509AsymmetricSecurityKey(cert); key.GetAsymmetricAlgorithm(SignedXml.XmlDsigHMACSHA1Url, false); }
public void GetAsymmetricAlgorithmDSA() { X509AsymmetricSecurityKey key = new X509AsymmetricSecurityKey(cert); AsymmetricAlgorithm alg = key.GetAsymmetricAlgorithm(SignedXml.XmlDsigDSAUrl, false); }
[Category("NotDotNet")] // buggy FormatException occurs instead public void GetAsymmetricAlgorithmNullAlgName() { X509AsymmetricSecurityKey key = new X509AsymmetricSecurityKey(cert); key.GetAsymmetricAlgorithm(null, false); }
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); }
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, })); }