private void AddIosSpecificParametersToPayload(Dictionary <string, string> brokerPayload) { string encodedBrokerKey = Base64UrlHelpers.Encode(BrokerKeyHelper.GetRawBrokerKey(_logger)); brokerPayload[iOSBrokerConstants.BrokerKey] = encodedBrokerKey; brokerPayload[iOSBrokerConstants.MsgProtocolVer] = BrokerParameter.MsgProtocolVersion3; if (_brokerV3Installed) { _brokerRequestNonce = Guid.NewGuid().ToString(); brokerPayload[iOSBrokerConstants.BrokerNonce] = _brokerRequestNonce; string applicationToken = TryReadBrokerApplicationTokenFromKeychain(brokerPayload); if (!string.IsNullOrEmpty(applicationToken)) { brokerPayload[iOSBrokerConstants.ApplicationToken] = applicationToken; } } if (brokerPayload.ContainsKey(iOSBrokerConstants.Claims)) { brokerPayload[iOSBrokerConstants.SkipCache] = BrokerParameter.SkipCache; string claims = Base64UrlHelpers.Encode(brokerPayload[BrokerParameter.Claims]); brokerPayload[BrokerParameter.Claims] = claims; } }
private string CreateJwkClaim(RsaSecurityKey key, string algorithm) { var parameters = key.Rsa == null ? key.Parameters : key.Rsa.ExportParameters(false); //return "{\"kty\":\"RSA\",\"n\":\"" + Base64UrlEncoder.Encode(parameters.Modulus) + "\",\"e\":\"" + Base64UrlEncoder.Encode(parameters.Exponent) + "\",\"alg\":\"" + algorithm + "\"}"; return($@"{{""e"":""{Base64UrlHelpers.Encode(parameters.Exponent)}"",""kty"":""RSA"",""n"":""{Base64UrlHelpers.Encode(parameters.Modulus)}""}}"); }
private string ComputeReqCnf() { // There are 4 possible formats for a JWK, but Evo supports only this one for simplicity var jwk = $@"{{""{JsonWebKeyParameterNames.Kid}"":""{KeyId}""}}"; return(Base64UrlHelpers.Encode(jwk)); }
public CertificateAndClaimsClientCredential(X509Certificate2 certificate, IDictionary <string, string> claimsToSign, bool appendDefaultClaims) { Certificate = certificate; _claimsToSign = claimsToSign; _appendDefaultClaims = appendDefaultClaims; _base64EncodedThumbprint = Base64UrlHelpers.Encode(certificate.GetCertHash()); }
/// <summary> /// A key ID that uniquely describes a public / private key pair. While KeyID is not normally /// strict, AAD support for PoP requires that we use the base64 encoded JWK thumbprint, as described by /// https://tools.ietf.org/html/rfc7638 /// </summary> private string GetKidFromJwk(string jwk) { using (SHA256 hash = SHA256.Create()) { byte[] hashBytes = hash.ComputeHash(Encoding.UTF8.GetBytes(jwk)); return(Base64UrlHelpers.Encode(hashBytes)); } }
/// <summary> /// Creates POP tokens, i.e. tokens that are bound to an HTTP request and are digitally signed. /// </summary> /// <remarks> /// Currently the signing credential algorithm is hard-coded to RSA with SHA256. Extensibility should be done /// by integrating Wilson's SigningCredentials /// </remarks> public PoPAuthenticationScheme(HttpRequestMessage httpRequestMessage, IPoPCryptoProvider popCryptoProvider) { _httpRequestMessage = httpRequestMessage ?? throw new ArgumentNullException(nameof(httpRequestMessage)); _popCryptoProvider = popCryptoProvider ?? throw new ArgumentNullException(nameof(popCryptoProvider)); _keyThumbprint = ComputeRsaThumbprint(_popCryptoProvider.CannonicalPublicKeyJwk); KeyId = Base64UrlHelpers.Encode(_keyThumbprint); }
/// <summary> /// Creates the cannonical representation of the JWK. See https://tools.ietf.org/html/rfc7638#section-3 /// The number of parameters as well as the lexicographic order is important, as this string will be hashed to get a thumbprint /// </summary> private static string ComputeCannonicalJwk(ECParameters ecdPublicKey) { string x = ecdPublicKey.Q.X != null?Base64UrlHelpers.Encode(ecdPublicKey.Q.X) : null; string y = ecdPublicKey.Q.Y != null?Base64UrlHelpers.Encode(ecdPublicKey.Q.Y) : null; return($@"{{""{JsonWebKeyParameterNames.Crv}"":""{GetCrvParameterValue(ecdPublicKey.Curve)}"",""{JsonWebKeyParameterNames.Kty}"":""{JsonWebKeyParameterNames.EC}"",""{JsonWebKeyParameterNames.X}"":""{x}"",""{JsonWebKeyParameterNames.Y}"":""{y}""}}"); }
public bool TryCreateDeviceAuthChallengeResponseAsync(HttpResponseHeaders responseHeaders, Uri endpointUri, out string responseHeader) { responseHeader = string.Empty; string authHeaderTemplate = "PKeyAuth {0}, Context=\"{1}\", Version=\"{2}\""; X509Certificate2 certificate = null; if (!DeviceAuthHelper.IsDeviceAuthChallenge(responseHeaders)) { return(false); } if (!DeviceAuthHelper.CanOSPerformPKeyAuth()) { responseHeader = DeviceAuthHelper.GetBypassChallengeResponse(responseHeaders); return(true); } IDictionary <string, string> challengeData = DeviceAuthHelper.ParseChallengeData(responseHeaders); if (!challengeData.ContainsKey("SubmitUrl")) { challengeData["SubmitUrl"] = endpointUri.AbsoluteUri; } try { certificate = FindCertificate(challengeData); } catch (MsalException ex) { if (ex.ErrorCode == MsalError.DeviceCertificateNotFound) { responseHeader = DeviceAuthHelper.GetBypassChallengeResponse(responseHeaders); return(true); } } DeviceAuthJWTResponse responseJWT = new DeviceAuthJWTResponse(challengeData["SubmitUrl"], challengeData["nonce"], Convert.ToBase64String(certificate.GetRawCertData())); CngKey key = NetDesktopCryptographyManager.GetCngPrivateKey(certificate); byte[] sig = null; using (Native.RSACng rsa = new Native.RSACng(key)) { rsa.SignatureHashAlgorithm = CngAlgorithm.Sha256; sig = rsa.SignData(responseJWT.GetResponseToSign().ToByteArray()); } string signedJwt = string.Format(CultureInfo.InvariantCulture, "{0}.{1}", responseJWT.GetResponseToSign(), Base64UrlHelpers.Encode(sig)); string authToken = string.Format(CultureInfo.InvariantCulture, " AuthToken=\"{0}\"", signedJwt); responseHeader = string.Format(CultureInfo.InvariantCulture, authHeaderTemplate, authToken, challengeData["Context"], challengeData["Version"]); return(true); }
public string GenerateCodeVerifier() { byte[] buffer = new byte[Constants.CodeVerifierByteSize]; var windowsBuffer = CryptographicBuffer.GenerateRandom((uint)buffer.Length); Array.Copy(windowsBuffer.ToArray(), buffer, buffer.Length); return(Base64UrlHelpers.Encode(buffer)); }
public string GenerateCodeVerifier() { byte[] buffer = new byte[Constants.CodeVerifierByteSize]; using (RNGCryptoServiceProvider randomSource = new RNGCryptoServiceProvider()) { randomSource.GetBytes(buffer); } return(Base64UrlHelpers.Encode(buffer)); }
private IdToken GetIdToken( string oid, string subject, string upn, string email) { var idTokenJson = JObject.Parse($"{{'oid': '{oid}', 'sub': '{subject}', 'upn': '{upn}', 'email': '{email}'}}"); return(new IdToken($".{Base64UrlHelpers.Encode(idTokenJson.ToString())}.")); }
public string GenerateCodeVerifier() { byte[] buffer = new byte[Constants.CodeVerifierByteSize]; using (var randomSource = RandomNumberGenerator.Create()) { randomSource.GetBytes(buffer); } return(Base64UrlHelpers.Encode(buffer)); }
private void FormatResponseHeader( DeviceAuthJWTResponse responseJWT, byte[] signedResponse, IDictionary <string, string> challengeData, out string responseHeader) { string signedJwt = $"{responseJWT.GetResponseToSign()}.{Base64UrlHelpers.Encode(signedResponse)}"; string authToken = $"AuthToken=\"{signedJwt}\""; responseHeader = $"PKeyAuth {authToken}, Context=\"{challengeData["Context"]}\", Version=\"{challengeData["Version"]}\""; }
private string CreateJwk() { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048); RSAParameters rsaKeyInfo = rsa.ExportParameters(false); string modulus = Base64UrlHelpers.Encode(rsaKeyInfo.Modulus); string exp = Base64UrlHelpers.Encode(rsaKeyInfo.Exponent); string jwk = $"{{\"kty\":\"RSA\", \"n\":\"{modulus}\", \"e\":\"{exp}\"}}"; return(jwk); }
public void SignWithCertificate() { //Tests the cryptography libraries used by MSAL to sign with certificates var cert = new X509Certificate2("testCert.crtfile", "passw0rd!"); CryptographyHelper helper = new CryptographyHelper(); byte[] result = helper.SignWithCertificate("TEST", cert); string value = Base64UrlHelpers.Encode(result); Assert.IsNotNull(value); Assert.AreEqual("MrknKHbOAVu2iuLHMFSk2SK773H1ysxaAjAPcTXYSfH4P2fUfvzP6aIb9MkBknjoE_aBYtTnQ7jOAvyQETvogdeSH7pRDPhCk2aX_8VIQw0bjo_zBZj5yJYVWQDLIu8XvbuzIGEvVaXKz4jJ1nYM6toun4tM74rEHvwa0ferafmqHWOd5puPhlKH1VVK2RPuNOoKNLWBprVBaAQVJVFOdRcd3iR0INBHykxtOsG0pgo0Q2uQBlKP7KQb7Ox8i_sw-M21BuUzdIdGs_oeUYh0B8s-eIGf34JmHRWMwWCnRWzZgY9YuIjRoaWNqlWYb8ASjKOxzvk99x8eFEYKOjgAcA", value); }
private static string GetSignedClientAssertionUsingMsalInternal(string clientId, IDictionary <string, string> claims) { #if NET_CORE var manager = new Client.Platforms.netcore.NetCoreCryptographyManager(); #else var manager = new Client.Platforms.net45.NetDesktopCryptographyManager(); #endif var jwtToken = new Client.Internal.JsonWebToken(manager, clientId, TestConstants.ClientCredentialAudience, claims); var cert = ConfidentialAppSettings.GetSettings(Cloud.Public).GetCertificate(); return(jwtToken.Sign(cert, Base64UrlHelpers.Encode(cert.GetCertHash()), true)); }
/// <summary> /// </summary> /// <returns></returns> public override string ToString() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(Base64UrlHelpers.Encode(Environment)); stringBuilder.Append(CacheKeyDelimiter); stringBuilder.Append(Base64UrlHelpers.Encode(ClientId)); stringBuilder.Append(CacheKeyDelimiter); stringBuilder.Append(Base64UrlHelpers.Encode(UserIdentifier)); return(stringBuilder.ToString()); }
public bool TryCreateDeviceAuthChallengeResponseAsync(HttpResponseHeaders headers, Uri endpointUri, out string responseHeader) { responseHeader = string.Empty; Certificate certificate = null; string authHeaderTemplate = "PKeyAuth {0}, Context=\"{1}\", Version=\"{2}\""; if (!DeviceAuthHelper.IsDeviceAuthChallenge(headers)) { return(false); } if (!DeviceAuthHelper.CanOSPerformPKeyAuth()) { responseHeader = DeviceAuthHelper.GetBypassChallengeResponse(headers); return(false); } IDictionary <string, string> challengeData = DeviceAuthHelper.ParseChallengeData(headers); if (!challengeData.ContainsKey("SubmitUrl")) { challengeData["SubmitUrl"] = endpointUri.AbsoluteUri; } try { certificate = Task.FromResult(FindCertificateAsync(challengeData)).Result.Result; } catch (MsalException ex) { if (ex.ErrorCode == MsalError.DeviceCertificateNotFound) { responseHeader = DeviceAuthHelper.GetBypassChallengeResponse(headers); return(true); } } DeviceAuthJWTResponse responseJWT = new DeviceAuthJWTResponse(challengeData["SubmitUrl"], challengeData["nonce"], Convert.ToBase64String(certificate.GetCertificateBlob().ToArray())); IBuffer input = CryptographicBuffer.ConvertStringToBinary(responseJWT.GetResponseToSign(), BinaryStringEncoding.Utf8); CryptographicKey keyPair = Task.FromResult(PersistedKeyProvider.OpenKeyPairFromCertificateAsync(certificate, HashAlgorithmNames.Sha256, CryptographicPadding.RsaPkcs1V15)).Result.GetResults(); IBuffer signed = Task.FromResult(CryptographicEngine.SignAsync(keyPair, input)).Result.GetResults(); string signedJwt = string.Format(CultureInfo.InvariantCulture, "{0}.{1}", responseJWT.GetResponseToSign(), Base64UrlHelpers.Encode(signed.ToArray())); string authToken = string.Format(CultureInfo.InvariantCulture, " AuthToken=\"{0}\"", signedJwt); responseHeader = string.Format(CultureInfo.InvariantCulture, authHeaderTemplate, authToken, challengeData["Context"], challengeData["Version"]); return(true); }
public void CreateFromJson_ValidJson_ReturnsClientInfo() { var clientInfoResult = ClientInfo.CreateFromJson(Base64UrlHelpers.Encode(_decodedJson)); Assert.NotNull(clientInfoResult); Assert.Equal(Uid, clientInfoResult.UniqueObjectIdentifier); Assert.Equal(Utid, clientInfoResult.UniqueTenantIdentifier); clientInfoResult = ClientInfo.CreateFromJson(Base64UrlHelpers.Encode(_decodedEmptyJson)); Assert.NotNull(clientInfoResult); Assert.Null(clientInfoResult.UniqueObjectIdentifier); Assert.Null(clientInfoResult.UniqueTenantIdentifier); }
public string CreateBase64UrlEncodedSha256Hash(string input) { if (string.IsNullOrEmpty(input)) { return(null); } using (SHA256Managed sha = new SHA256Managed()) { UTF8Encoding encoding = new UTF8Encoding(); return(Base64UrlHelpers.Encode(sha.ComputeHash(encoding.GetBytes(input)))); } }
private void AddIosSpecificParametersToPayload(Dictionary <string, string> brokerPayload) { string encodedBrokerKey = Base64UrlHelpers.Encode(BrokerKeyHelper.GetRawBrokerKey(_serviceBundle.DefaultLogger)); brokerPayload[iOSBrokerConstants.BrokerKey] = encodedBrokerKey; brokerPayload[iOSBrokerConstants.MsgProtocolVer] = BrokerParameter.MsgProtocolVersion3; if (brokerPayload.ContainsKey(iOSBrokerConstants.Claims)) { brokerPayload.Add(iOSBrokerConstants.SkipCache, BrokerParameter.SkipCache); string claims = Base64UrlHelpers.Encode(brokerPayload[BrokerParameter.Claims]); brokerPayload[BrokerParameter.Claims] = claims; } }
/// <summary> /// Creates a JWS (json web signature) as per: https://tools.ietf.org/html/rfc7515 /// Format: header.payload.signed_payload /// </summary> private string CreateJWS(string payload, string header) { StringBuilder sb = new StringBuilder(); sb.Append(Base64UrlHelpers.Encode(Encoding.UTF8.GetBytes(header))); sb.Append("."); sb.Append(Base64UrlHelpers.Encode(payload)); string headerAndPayload = sb.ToString(); sb.Append("."); sb.Append(Base64UrlHelpers.Encode(_popCryptoProvider.Sign(Encoding.UTF8.GetBytes(headerAndPayload)))); return(sb.ToString()); }
/// <summary> /// Creates POP tokens, i.e. tokens that are bound to an HTTP request and are digitally signed. /// </summary> /// <remarks> /// Currently the signing credential algorithm is hard-coded to RSA with SHA256. Extensibility should be done /// by integrating Wilson's SigningCredentials /// </remarks> public PoPAuthenticationScheme(PoPAuthenticationConfiguration popAuthenticationConfiguration, IServiceBundle serviceBundle) { if (serviceBundle == null) { throw new ArgumentNullException(nameof(serviceBundle)); } _popAuthenticationConfiguration = popAuthenticationConfiguration ?? throw new ArgumentNullException(nameof(popAuthenticationConfiguration)); _popAuthenticationConfiguration.PopCryptoProvider = _popAuthenticationConfiguration.PopCryptoProvider ?? serviceBundle.PlatformProxy.GetDefaultPoPCryptoProvider(); var keyThumbprint = ComputeThumbprint(_popAuthenticationConfiguration.PopCryptoProvider.CannonicalPublicKeyJwk); KeyId = Base64UrlHelpers.Encode(keyThumbprint); }
private (HttpContext, AuthenticationScheme, AuthenticationProperties) CreateContextParameters(IServiceProvider provider) { var httpContext = HttpContextUtilities.CreateHttpContext(); httpContext.RequestServices = provider; httpContext.Request.Form = new FormCollection( new Dictionary <string, StringValues>() { { ClaimConstants.ClientInfo, Base64UrlHelpers.Encode($"{{\"uid\":\"{TestConstants.Uid}\",\"utid\":\"{TestConstants.Utid}\"}}") } }); var authScheme = new AuthenticationScheme(OpenIdConnectDefaults.AuthenticationScheme, OpenIdConnectDefaults.AuthenticationScheme, typeof(OpenIdConnectHandler)); var authProperties = new AuthenticationProperties(); return(httpContext, authScheme, authProperties); }
public string CreateBase64UrlEncodedSha256Hash(string input) { if (string.IsNullOrEmpty(input)) { return(null); } IBuffer inputBuffer = CryptographicBuffer.ConvertStringToBinary(input, BinaryStringEncoding.Utf8); var hasher = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256); IBuffer hashed = hasher.HashData(inputBuffer); string output = CryptographicBuffer.EncodeToBase64String(hashed); return(Base64UrlHelpers.Encode(Convert.FromBase64String(output))); }
/// <summary> /// </summary> /// <returns></returns> public override string ToString() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(Base64UrlHelpers.Encode(Authority)); stringBuilder.Append(CacheKeyDelimiter); stringBuilder.Append(Base64UrlHelpers.Encode(ClientId)); stringBuilder.Append(CacheKeyDelimiter); // scope is treeSet to guarantee the order of the scopes when converting to string. stringBuilder.Append(Base64UrlHelpers.Encode(Scope.AsSingleString())); stringBuilder.Append(CacheKeyDelimiter); stringBuilder.Append(Base64UrlHelpers.Encode(UserIdentifier)); return(stringBuilder.ToString()); }
public void CreateFromJson_ValidJson_ReturnsClientInfo() { var decodedJson = $"{{\"uid\":\"{TestConstants.Uid}\",\"utid\":\"{TestConstants.Utid}\"}}"; var clientInfoResult = ClientInfo.CreateFromJson(Base64UrlHelpers.Encode(decodedJson)); Assert.NotNull(clientInfoResult); Assert.Equal(TestConstants.Uid, clientInfoResult.UniqueObjectIdentifier); Assert.Equal(TestConstants.Utid, clientInfoResult.UniqueTenantIdentifier); var decodedEmptyJson = "{}"; clientInfoResult = ClientInfo.CreateFromJson(Base64UrlHelpers.Encode(decodedEmptyJson)); Assert.NotNull(clientInfoResult); Assert.Null(clientInfoResult.UniqueObjectIdentifier); Assert.Null(clientInfoResult.UniqueTenantIdentifier); }
/// <summary> /// Creates a signed assertion in JWT format which can be used in the client_credentials flow. /// </summary> /// <param name="issuer">the client ID</param> /// <param name="audience">the token endpoint, i.e. ${authority}/oauth2/v2.0/token for AAD or ${authority}/oauth2/token for ADFS</param> /// <param name="certificate"></param> /// <returns></returns> internal static string GetSignedClientAssertionManual( string issuer, string audience, X509Certificate2 certificate) { const uint JwtToAadLifetimeInSeconds = 60 * 10; // Ten minutes DateTimeOffset now = DateTimeOffset.UtcNow; DateTimeOffset validFrom = now; // AAD will take clock skew into consideration DateTimeOffset validUntil = now.AddSeconds(JwtToAadLifetimeInSeconds); // as per https://datatracker.ietf.org/doc/html/rfc7523#section-3 // more claims can be added here var claims = new Dictionary <string, object>() { { "aud", audience }, { "exp", validUntil.ToUnixTimeSeconds() }, { "iss", issuer }, { "jti", Guid.NewGuid().ToString() }, { "nbf", validFrom.ToUnixTimeSeconds() }, { "sub", issuer } }; RSACng rsa = certificate.GetRSAPrivateKey() as RSACng; //alg represents the desired signing algorithm, which is SHA-256 in this case //kid represents the certificate thumbprint var header = new Dictionary <string, string>() { { "alg", "RS256" }, { "typ", "JWT" }, { "x5t", Base64UrlHelpers.Encode(certificate.GetCertHash()) }, }; var headerBytes = JsonSerializer.SerializeToUtf8Bytes(header); var claimsBytes = JsonSerializer.SerializeToUtf8Bytes(claims); string token = Base64UrlHelpers.Encode(headerBytes) + "." + Base64UrlHelpers.Encode(claimsBytes); string signature = Base64UrlHelpers.Encode( rsa.SignData( Encoding.UTF8.GetBytes(token), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1)); return(string.Concat(token, ".", signature)); }
public void Encode_DecodedString_ReturnsEncodedString() { var stringToEncodeNoPadding = "123456"; var expectedEncodedString = "MTIzNDU2"; var actualEncodedString = Base64UrlHelpers.Encode(stringToEncodeNoPadding); Assert.Equal(expectedEncodedString, actualEncodedString); var stringToEncode1Padding = "12345678"; var expectedEncodedString1Padding = "MTIzNDU2Nzg"; actualEncodedString = Base64UrlHelpers.Encode(stringToEncode1Padding); Assert.Equal(expectedEncodedString1Padding, actualEncodedString); var stringToEncode2Padding = "1234567"; var expectedEncodedString2Padding = "MTIzNDU2Nw"; actualEncodedString = Base64UrlHelpers.Encode(stringToEncode2Padding); Assert.Equal(expectedEncodedString2Padding, actualEncodedString); var stringToEncodeWithBase64Plus = "12>123"; var expectedEncodedStringWithBase64Plus = "MTI-MTIz"; actualEncodedString = Base64UrlHelpers.Encode(stringToEncodeWithBase64Plus); Assert.Equal(expectedEncodedStringWithBase64Plus, actualEncodedString); var stringToEncodeWithBase64Slash = "12?123"; var expectedEncodedStringWithBase64Slash = "MTI_MTIz"; actualEncodedString = Base64UrlHelpers.Encode(stringToEncodeWithBase64Slash); Assert.Equal(expectedEncodedStringWithBase64Slash, actualEncodedString); var emptyStringToEncode = string.Empty; actualEncodedString = Base64UrlHelpers.Encode(emptyStringToEncode); Assert.Equal(emptyStringToEncode, actualEncodedString); }
private void AddCommunicationParams(Dictionary <string, string> brokerRequest) { string encodedBrokerKey = Base64UrlHelpers.Encode(BrokerKeyHelper.GetRawBrokerKey(_logger)); brokerRequest[iOSBrokerConstants.BrokerKey] = encodedBrokerKey; brokerRequest[iOSBrokerConstants.MsgProtocolVer] = BrokerParameter.MsgProtocolVersion3; if (_brokerV3Installed) { _brokerRequestNonce = Guid.NewGuid().ToString(); brokerRequest[iOSBrokerConstants.BrokerNonce] = _brokerRequestNonce; string applicationToken = TryReadBrokerApplicationTokenFromKeychain(brokerRequest); if (!string.IsNullOrEmpty(applicationToken)) { brokerRequest[iOSBrokerConstants.ApplicationToken] = applicationToken; } } }