/// <summary> /// Generates a JWT with RSA512 using a private key loaded from the environment. /// </summary> /// <remarks> /// A JWT is compromised of 3 dot-separated, base64 strings. /// Jose_Header.JWT_Payload.JWT_Signature /// </remarks> /// <param name="payload">The data to be encrypted.</param> /// <returns>The JWT.</returns> public string GenerateJWT(Dictionary <string, string> payload) { // TODO CHECK PUBLIC KEY AND PRIVATE KEY, CHECK THEIR LENGTHS AND IF THEY INCLUDE ----BEGIN... ---END... ETC // Make sure we have the proper parameters inside the dictionary if (!payload.ContainsKey(Constants.UserTypeKey) || !payload.ContainsKey(Constants.IdKey)) { throw new ArgumentException("UserType or ID was not provided."); } // Create the header and convert it to a Base64 string Dictionary <string, string> joseHeader = new Dictionary <string, string> { { Constants.MediaType, Constants.MediaJWT }, // Media type { Constants.SigningAlgKey, Constants.SIGNING_ALGORITHM } // Signing algorithm type }; // If the expiration date wasn't already specified, then create one if (!payload.ContainsKey(Constants.EXPIRATION_FIELD)) { // Add a 20 min expiration payload.Add(Constants.EXPIRATION_FIELD, TimeUtilityService.GetEpochFromNow().ToString()); } // Base64 encode the header and payload string encodedHeader = StringUtilityService.DictionaryToString(joseHeader).ToBase64URL(); string encodedPayload = StringUtilityService.DictionaryToString(payload).ToBase64URL(); // The signature will be the hash of the header and payload string stringToSign = encodedHeader + '.' + encodedPayload; // Create the signature string signature = GetPKCSSignature(stringToSign).ToBase64URL(); return(string.Format("{0}.{1}.{2}", encodedHeader, encodedPayload, signature)); }
/// <summary> /// Hash a string data with HMAC SHA256. /// </summary> /// <param name="data"> a string to be hashed </param> /// <returns> a string of hash code </returns> public static string HashWithSHA256(string data) { using (SHA256CryptoServiceProvider sha256 = new SHA256CryptoServiceProvider()) { return(StringUtilityService.BytesToHexString(sha256.ComputeHash(Encoding.ASCII.GetBytes(data)))); } }
/// <summary> /// Hashes the string with SHA1. /// </summary> /// <param name="str">The input to be hashed </param> /// <returns>Hex string of the hashed input</returns> public static string HashWithSHA1(string str) { using (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider()) { // Convert the str to ASCII byte array -> // Compute the hashcode in byte array with the ASCII byte array -> // Convert the hashcode byte array to a hex string return(StringUtilityService.BytesToHexString(sha1.ComputeHash(Encoding.ASCII.GetBytes(str)))); } }
/// <summary> /// Hash a password with SHA3-256 KDF. /// </summary> /// <param name="password"> password to be hashed</param> /// <param name="salt"> salt used for hashing </param> /// <param name="iterations"> number of iterations </param> /// <param name="hashLength"> the length of the output hashcode </param> /// <returns> a string of derived key </returns> public static string HashWithKDF(string password, byte[] salt, int iterations = Constants.DefaultHashIterations, int hashLength = Constants.DefaultHashByteLength) { byte[] passwordBytes = StringUtilityService.HexStringToBytes(password); Pkcs5S2ParametersGenerator pbkdf = new Pkcs5S2ParametersGenerator(new Sha3Digest()); pbkdf.Init(passwordBytes, salt, iterations); KeyParameter derivedKey = pbkdf.GenerateDerivedMacParameters(hashLength * Constants.ByteLength) as KeyParameter; return(StringUtilityService.BytesToHexString(derivedKey.GetKey())); }
/// <summary> /// Decrypts a JWT in order to verify it and see the payload. /// </summary> /// <param name="jwt">The token to decrypt.</param> /// <returns>The contents inside the token.</returns> public Dictionary <string, string> DecryptJWT(string jwt) { string[] segments = jwt.Split('.'); // Make sure we have the proper JWT format of 3 tokens delimited by periods if (segments.Length != 3) { throw new InvalidTokenException("JWT must have 3 segments separated by periods."); } string encodedHeader = segments[0]; string encodedPayload = segments[1]; // Convert header back to dictionary format string decodedHeader = segments[0].FromBase64URL(); Dictionary <string, string> headerJSON = StringUtilityService.StringToDictionary(decodedHeader); // Convert payload back to dictionary format string decodedPayload = segments[1].FromBase64URL(); Dictionary <string, string> payloadJSON = StringUtilityService.StringToDictionary(decodedPayload); // Make sure that we are using the correct encryption algorithm in the header if (headerJSON[Constants.SigningAlgKey] != Constants.SIGNING_ALGORITHM) { throw new InvalidTokenException("Incorrect encryption algorithm."); } string strToVerify = encodedHeader + '.' + encodedPayload; // Make sure the signature is correct if (VerifyPKCSSignature(strToVerify)) { return(payloadJSON); } else { throw new InvalidTokenException("JWT could not be verified!"); } }
public VerifyUploadResult VerifyUpload(UploadDTO dto, int maxPhotoChars, int minPhotoChars, double minimumImageSizeMB, double maximumImageSizeMB, List <string> validExtensions, int ingredientNameMaxChars, int ingredientNameMinChars, double maxIngredientPrice, int descriptionMaxChars, int descriptionMinChars, List <string> validCategories, List <string> validPriceUnits, int validTimeBufferMinutes, int maxRating, int minRating) { var validPhotoPath = StringUtilityService.CheckLength(dto.ImagePath, maxPhotoChars, minPhotoChars); if (!validPhotoPath) { return(new VerifyUploadResult(Constants.ImagePathInvalidMessage, false)); } var sizeMB = dto.ImageSize * Constants.ToMBConversionFactor; var validSize = sizeMB >= minimumImageSizeMB && sizeMB <= maximumImageSizeMB; if (!validSize) { return(new VerifyUploadResult(Constants.ImageNotWithinSizeMessage, false)); } var fileExtension = "." + dto.ImagePath.Split('.').Last(); var validExt = false; foreach (var ext in validExtensions) { validExt = validExt || (fileExtension.ToLower().Equals(ext.ToLower())); } if (!validExt) { return(new VerifyUploadResult(Constants.ExtensionNotValidMessage, false)); } var validCat = false; foreach (var cat in validCategories) { validCat = validCat || (dto.Category.ToLower().Equals(cat.ToLower())); } if (!validCat) { return(new VerifyUploadResult(Constants.CategoryNotValidMessage, false)); } if (!dto.Name.Equals(Constants.NoValueString)) { var validNameLength = StringUtilityService.CheckLength(dto.Name, ingredientNameMaxChars, ingredientNameMinChars); if (!validNameLength) { return(new VerifyUploadResult(Constants.IngredientNameLengthInvalidMessage, false)); } } if (!dto.Price.Equals(Constants.NoValueDouble)) { var validPrice = dto.Price > Constants.NoValueDouble && dto.Price <= maxIngredientPrice; if (!validPrice) { return(new VerifyUploadResult(Constants.PriceInvalidMessage, false)); } } if (!dto.Description.Equals(Constants.NoValueString)) { var validDescriptionLength = StringUtilityService.CheckLength(dto.Description, descriptionMaxChars, descriptionMinChars); if (!validDescriptionLength) { return(new VerifyUploadResult(Constants.DescriptionLengthInvalidMessage, false)); } } if (!dto.PriceUnit.Equals(Constants.NoValueString)) { var validUnit = false; foreach (var unit in validPriceUnits) { validUnit = validUnit || (dto.PriceUnit.ToLower().Equals(unit.ToLower())); } if (!validUnit) { return(new VerifyUploadResult(Constants.PriceUnitNotValidMessage, false)); } } if (!dto.Time.Equals(Constants.NoValueDatetime)) { var validTime = (DateTime.Now - dto.Time).TotalMinutes <= validTimeBufferMinutes; if (!validTime) { return(new VerifyUploadResult(Constants.TimeNotValidMessage, false)); } } if (!dto.Rating.Equals(Constants.NoValueInt)) { var validRating = dto.Rating >= minRating && dto.Rating <= maxRating; if (!validRating) { return(new VerifyUploadResult(Constants.InvalidRatingMessage, false)); } } return(new VerifyUploadResult(Constants.NoValueString, true)); }