/// <summary> /// Creates a <see cref="SecurityToken"/> instance from the parsed encrypted <paramref name="securityToken"/>. /// The token itself is decrypted using the <see cref="AdvancedEncryptionStandardUtility.Decrypt"/> method. /// </summary> /// <param name="securityToken">The security token to parse.</param> /// <param name="securityKey">The key to use in the decryption algorithm.</param> /// <param name="securityInitializationVector">The initialization vector (IV) to use in the decryption algorithm.</param> /// <returns>An instance of the <see cref="SecurityToken"/> object.</returns> public static SecurityToken ParseEncryptedSecurityToken(byte[] securityToken, byte[] securityKey, byte[] securityInitializationVector) { return(SecurityToken.Parse(StringConverter.FromBytes(AdvancedEncryptionStandardUtility.Decrypt(securityToken, securityKey, securityInitializationVector), options => { options.Encoding = Encoding.UTF8; options.Preamble = PreambleSequence.Remove; }))); }
/// <summary> /// Creates a security token easily adopted into various services in the format of the <see cref="SecurityToken.ToString()"/> method. /// The token itself is encrypted using the <see cref="AdvancedEncryptionStandardUtility.Encrypt"/> method. /// </summary> /// <param name="token">The <see cref="SecurityToken"/> to convert and encrypt to a byte[] representation.</param> /// <param name="securityKey">The key to use in the encryption algorithm.</param> /// <param name="securityInitializationVector">The initialization vector (IV) to use in the encryption algorithm.</param> /// <returns>A security token easily adopted into various services in the format of the <see cref="SecurityToken.ToString()"/> method.</returns> public static byte[] CreateEncryptedSecurityToken(SecurityToken token, byte[] securityKey, byte[] securityInitializationVector) { if (token == null) { throw new ArgumentNullException(nameof(token)); } byte[] securityToken = AdvancedEncryptionStandardUtility.Encrypt(ByteConverter.FromString(token.ToString(), options => { options.Encoding = Encoding.UTF8; options.Preamble = PreambleSequence.Remove; }), securityKey, securityInitializationVector); return(securityToken); }
/// <summary> /// Revert the obfuscated XML document of <paramref name="value"/> to its original state by applying the mappable XML document of <paramref name="mapping"/>. /// </summary> /// <param name="value">The obfuscated <see cref="Stream"/> to revert.</param> /// <param name="mapping">A <see cref="Stream"/> containing mappable values necessary to revert <paramref name="value"/> to its original state.</param> /// <returns> /// A <see cref="Stream"/> object where the obfuscated XML document has been reverted to its original XML document. /// </returns> public override Stream Revert(Stream value, Stream mapping) { if (value == null) { throw new ArgumentNullException(nameof(value)); } if (mapping == null) { throw new ArgumentNullException(nameof(mapping)); } MemoryStream tempOutput = null; try { XmlDocument document = XmlDocumentConverter.FromStream(mapping); var mappingNode = document.DocumentElement; XmlNode encryptedNode = mappingNode.GetElementsByTagName(MappingEncryptedElement).Item(0); if (encryptedNode != null) { mappingNode.InnerXml = StringConverter.FromBytes(AdvancedEncryptionStandardUtility.Decrypt(Convert.FromBase64String(encryptedNode.InnerText), Key, InitializationVector), options => { options.Encoding = Encoding; options.Preamble = PreambleSequence.Remove; }); } tempOutput = new MemoryStream(); using (XmlWriter writer = XmlWriter.Create(tempOutput, XmlWriterUtility.CreateSettings(o => o.Encoding = Encoding))) { document.WriteTo(writer); } tempOutput.Position = 0; mapping = tempOutput; tempOutput = null; } finally { if (tempOutput != null) { tempOutput.Dispose(); } } return(base.Revert(value, mapping)); }
/// <summary> /// Converts the specified <paramref name="uriLocation"/> to a tampering protected <see cref="Uri"/>. /// </summary> /// <param name="uriLocation">The URI to protect from tampering.</param> /// <param name="securityKey">The security key to use for the <see cref="SecurityToken"/> encryption.</param> /// <param name="settings">The settings to apply to the <see cref="SecurityToken"/>.</param> /// <param name="algorithmType">The hash algorithm to use for the URI checksum computation. Default is <b><see cref="HashAlgorithmType.SHA1"/></b>.</param> /// <param name="secureUriFormat">The naming format of the required query string parameters of the tamper protected URI. Default is <b>?token={0}&iv={1}&salt={2}</b>, where you can change the naming of the query string parameters.</param> /// <param name="querystringParameterHashName">The name of the checksum parameter to append to the tampering protected URI. Default is <b>hash</b>.</param> /// <returns>An URI equivalent to the <paramref name="uriLocation"/> but protected from tampering - including but not limited to - MITM attacks.</returns> public static Uri CreateTamperingProtectedUri(string uriLocation, byte[] securityKey, SecurityTokenSettings settings, HashAlgorithmType algorithmType, string secureUriFormat, string querystringParameterHashName) { Validator.ThrowIfNullOrEmpty(uriLocation, nameof(uriLocation)); Validator.ThrowIfNull(securityKey, nameof(securityKey)); Validator.ThrowIfNull(settings, nameof(settings)); Validator.ThrowIfEqual(securityKey.Length, 0, nameof(securityKey)); Validator.ThrowIfNullOrEmpty(secureUriFormat, nameof(secureUriFormat)); int foundArguments; if (!StringUtility.ParseFormat(secureUriFormat, 3, out foundArguments)) { throw new ArgumentException("You must - in this order - specify three arguments for; 'token', 'iv' and 'salt'. This value cannot be exceeded nor the opposite. 'token', 'iv' and 'salt' is the default values."); } NameValueCollection formatedQuerytring = QueryStringConverter.FromString(secureUriFormat); SecurityToken securityToken = SecurityToken.Create(settings); byte[] iv = AdvancedEncryptionStandardUtility.GenerateInitializationVector(); byte[] encryptedSecurityToken = SecurityUtility.CreateEncryptedSecurityToken(securityToken, securityKey, iv); string ivAsString = HttpUtility.UrlEncode(Encoding.UTF8.GetString(iv, 0, iv.Length)); string encryptedSecurityTokenAsString = HttpUtility.UrlEncode(Convert.ToBase64String(encryptedSecurityToken)); string salt = HttpUtility.UrlEncode(StringUtility.CreateRandomString(18)); int indexOfQuestionMark = uriLocation.IndexOf('?'); string uriLocationQuerystring = indexOfQuestionMark > 0 ? uriLocation.Substring(indexOfQuestionMark) : ""; uriLocation = indexOfQuestionMark > 0 ? uriLocation.Substring(0, indexOfQuestionMark) : uriLocation; NameValueCollection querystring = QueryStringConverter.FromString(uriLocationQuerystring); NameValueCollection secureQuerystring = QueryStringConverter.FromString(string.Format(CultureInfo.InvariantCulture, secureUriFormat, encryptedSecurityTokenAsString, ivAsString, salt)); secureQuerystring.Add(querystring); querystring = QueryStringUtility.RemoveDublets(secureQuerystring, formatedQuerytring.AllKeys); string secureUri = string.Format(CultureInfo.InvariantCulture, "{0}{1}", uriLocation, QueryStringConverter.FromNameValueCollection(querystring)); secureUri += string.Format(CultureInfo.InvariantCulture, "&{0}={1}", querystringParameterHashName, HashUtility.ComputeHash(secureUri + salt + securityToken.Token, o => { o.AlgorithmType = algorithmType; o.Encoding = Encoding.UTF8; }).ToHexadecimal()); return(new Uri(secureUri)); }
/// <summary> /// Creates and returns a mappable XML document of the original values and the obfuscated values. /// </summary> /// <returns>A mappable XML document of the original values and the obfuscated values.</returns> public override Stream CreateMapping() { MemoryStream output; MemoryStream tempOutput = null; try { XmlDocument document = XmlDocumentConverter.FromStream(base.CreateMapping()); XmlNode mappingNode = document.DocumentElement; string innerXmlOfMappingNode = mappingNode.InnerXml; byte[] innerXmlOfMappingNodeBytes = ByteConverter.FromString(innerXmlOfMappingNode, options => { options.Encoding = Encoding; options.Preamble = PreambleSequence.Remove; }); XmlElement encryptedNode = document.CreateElement(MappingEncryptedElement); encryptedNode.InnerText = Convert.ToBase64String(AdvancedEncryptionStandardUtility.Encrypt(innerXmlOfMappingNodeBytes, Key, InitializationVector)); mappingNode.InnerXml = ""; mappingNode.AppendChild(encryptedNode); tempOutput = new MemoryStream(); using (XmlWriter writer = XmlWriter.Create(tempOutput, XmlWriterUtility.CreateSettings(o => o.Encoding = Encoding))) { document.WriteTo(writer); } tempOutput.Position = 0; output = tempOutput; tempOutput = null; } finally { if (tempOutput != null) { tempOutput.Dispose(); } } return(output); }