signature.cs 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Security.Cryptography;
  5. using System.Text;
  6. namespace ImgProxy.Examples
  7. {
  8. class Program
  9. {
  10. static void Main(string[] args)
  11. {
  12. const string Key = "943b421c9eb07c830af81030552c86009268de4e532ba2ee2eab8247c6da0881";
  13. const string Salt = "520f986b998545b4785e0defbc4f3c1203f22de2374a3d53cb7a7fe9fea309c5";
  14. const string Url = "http://img.example.com/pretty/image.jpg";
  15. const string Resize = "fill";
  16. const int Width = 300;
  17. const int Height = 300;
  18. const string Gravity = "no";
  19. const int Enlarge = 1;
  20. const string Extension = "png";
  21. var url = SignerHelper.GenerateUrl(Key, Salt, Url, Resize, Width, Height, Gravity, Enlarge, Extension);
  22. Console.WriteLine(url);
  23. }
  24. }
  25. public static class SignerHelper
  26. {
  27. public static string GenerateUrl(string key, string salt, string url, string resize, int width, int height, string gravity, int enlarge, string extension)
  28. {
  29. var keybin = HexadecimalStringToByteArray(key);
  30. var saltBin = HexadecimalStringToByteArray(salt);
  31. var encodedUrl = EncodeBase64URLSafeString(url);
  32. var path = $"/rs:{resize}:{width}:{height}:{enlarge}/g:{gravity}/{encodedUrl}.{extension}";
  33. var passwordWithSaltBytes = new List<byte>();
  34. passwordWithSaltBytes.AddRange(saltBin);
  35. passwordWithSaltBytes.AddRange(Encoding.UTF8.GetBytes(path));
  36. using var hmac = new HMACSHA256(keybin);
  37. byte[] digestBytes = hmac.ComputeHash(passwordWithSaltBytes.ToArray());
  38. var urlSafeBase64 = EncodeBase64URLSafeString(digestBytes);
  39. return $"/{urlSafeBase64}{path}";
  40. }
  41. static byte[] HexadecimalStringToByteArray(string input)
  42. {
  43. var outputLength = input.Length / 2;
  44. var output = new byte[outputLength];
  45. using (var sr = new StringReader(input))
  46. {
  47. for (var i = 0; i < outputLength; i++)
  48. output[i] = Convert.ToByte(new string(new char[2] { (char)sr.Read(), (char)sr.Read() }), 16);
  49. }
  50. return output;
  51. }
  52. static string EncodeBase64URLSafeString(this byte[] stream)
  53. => Convert.ToBase64String(stream).TrimEnd('=').Replace('+', '-').Replace('/', '_');
  54. static string EncodeBase64URLSafeString(this string str)
  55. => EncodeBase64URLSafeString(Encoding.ASCII.GetBytes(str));
  56. }
  57. }