1
0
mirror of https://github.com/imgproxy/imgproxy.git synced 2025-02-02 11:34:20 +02:00

Refactor C# sample / fix generation fail on some url supplied with queries parameters (#515)

Co-authored-by: REY Nicolas <nicolas.rey@interflora.fr>
This commit is contained in:
Nicolas REY 2020-12-02 09:19:17 +01:00 committed by GitHub
parent dd6bac73cc
commit fe333f6487
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Security.Cryptography;
using System.Text;
@ -21,40 +21,48 @@ namespace ImgProxy.Examples
const int Enlarge = 1;
const string Extension = "png";
var url = GenerateUrl(Key, Salt, Url, Resize, Width, Height, Gravity, Enlarge, Extension);
var url = SignerHelper.GenerateUrl(Key, Salt, Url, Resize, Width, Height, Gravity, Enlarge, Extension);
Console.WriteLine(url);
}
}
static string GenerateUrl(string key, string salt, string url, string resize, int width, int height, string gravity, int enlarge, string extension)
public static class SignerHelper
{
public static string GenerateUrl(string key, string salt, string url, string resize, int width, int height, string gravity, int enlarge, string extension)
{
var keybin = StringToByteArray(key);
var saltBin = StringToByteArray(salt);
var encodedUrl = string.Join("/", WholeChunks(Convert.ToBase64String(Encoding.UTF8.GetBytes(url)).TrimEnd('='), 16));
var keybin = HexadecimalStringToByteArray(key);
var saltBin = HexadecimalStringToByteArray(salt);
var encodedUrl = EncodeBase64URLSafeString(url);
var path = $"/{resize}/{width}/{height}/{gravity}/{enlarge}/{encodedUrl}.{extension}";
using (var hmac = new HMACSHA256(keybin))
var passwordWithSaltBytes = new List<byte>();
passwordWithSaltBytes.AddRange(saltBin);
passwordWithSaltBytes.AddRange(Encoding.UTF8.GetBytes(path));
using var hmac = new HMACSHA256(keybin);
byte[] digestBytes = hmac.ComputeHash(passwordWithSaltBytes.ToArray());
var urlSafeBase64 = EncodeBase64URLSafeString(digestBytes);
return $"/{urlSafeBase64}{path}";
}
static byte[] HexadecimalStringToByteArray(string input)
{
var outputLength = input.Length / 2;
var output = new byte[outputLength];
using (var sr = new StringReader(input))
{
var hash = hmac.ComputeHash(saltBin.Concat(Encoding.UTF8.GetBytes(path)).ToArray());
var urlSafeBase64 = Convert.ToBase64String(hash).TrimEnd('=').Replace('+', '-').Replace('/', '_');
return $"/{urlSafeBase64}{path}";
for (var i = 0; i < outputLength; i++)
output[i] = Convert.ToByte(new string(new char[2] { (char)sr.Read(), (char)sr.Read() }), 16);
}
return output;
}
static byte[] StringToByteArray(string hex)
{
return Enumerable.Range(0, hex.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
.ToArray();
}
static string EncodeBase64URLSafeString(this byte[] stream)
=> Convert.ToBase64String(stream).TrimEnd('=').Replace('+', '-').Replace('/', '_');
static IEnumerable<string> WholeChunks(string str, int maxChunkSize)
{
for (int i = 0; i < str.Length; i += maxChunkSize)
yield return str.Substring(i, Math.Min(maxChunkSize, str.Length - i));
}
static string EncodeBase64URLSafeString(this string str)
=> EncodeBase64URLSafeString(Encoding.ASCII.GetBytes(str));
}
}