diff --git a/examples/encrypted_source_url.go b/examples/encrypted_source_url.go index 2d5d33b9..fceef3db 100644 --- a/examples/encrypted_source_url.go +++ b/examples/encrypted_source_url.go @@ -1,7 +1,4 @@ -//go:build exclude -// +build exclude - -package main +package examples import ( "bytes" @@ -21,7 +18,7 @@ func pkcs7pad(data []byte, blockSize int) []byte { return append(data, padding...) } -func main() { +func ExcryptSourceURL() { key := "1eb5b0e971ad7f45324c1bb15c947cb207c43152fa5c6c7f35c4f36e0c18e0f1" var ( diff --git a/examples/signature-truncated.php b/examples/signature-truncated.php index 3239aa66..1f6f6df6 100644 --- a/examples/signature-truncated.php +++ b/examples/signature-truncated.php @@ -15,17 +15,8 @@ if(empty($saltBin)) { die('Salt expected to be hex-encoded string'); } -$resize = 'fill'; -$width = 300; -$height = 300; -$gravity = 'no'; -$enlarge = 1; -$extension = 'png'; +$path = "/rs:fit:300:300/plain/http://img.example.com/pretty/image.jpg"; -$url = 'http://img.example.com/pretty/image.jpg'; -$encodedUrl = rtrim(strtr(base64_encode($url), '+/', '-_'), '='); - -$path = "/rs:{$resize}:{$width}:{$height}:{$enlarge}/g:{$gravity}/{$encodedUrl}.{$extension}"; $signature = hash_hmac('sha256', $saltBin.$path, $keyBin, true); $signature = pack('A'.IMGPROXY_SIGNATURE_SIZE, $signature); $signature = rtrim(strtr(base64_encode($signature), '+/', '-_'), '='); diff --git a/examples/signature.cs b/examples/signature.cs index e2210ca5..07aecb5c 100644 --- a/examples/signature.cs +++ b/examples/signature.cs @@ -12,16 +12,8 @@ namespace ImgProxy.Examples { const string Key = "943b421c9eb07c830af81030552c86009268de4e532ba2ee2eab8247c6da0881"; const string Salt = "520f986b998545b4785e0defbc4f3c1203f22de2374a3d53cb7a7fe9fea309c5"; - const string Url = "http://img.example.com/pretty/image.jpg"; - const string Resize = "fill"; - const int Width = 300; - const int Height = 300; - const string Gravity = "no"; - const int Enlarge = 1; - const string Extension = "png"; - - var url = SignerHelper.GenerateUrl(Key, Salt, Url, Resize, Width, Height, Gravity, Enlarge, Extension); + var path = SignerHelper.SignPath(Key, Salt, "/rs:fit:300:300/plain/http://img.example.com/pretty/image.jpg"); Console.WriteLine(url); } @@ -29,14 +21,11 @@ namespace ImgProxy.Examples 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) + public static string SignPath(string key, string salt, string path) { var keybin = HexadecimalStringToByteArray(key); var saltBin = HexadecimalStringToByteArray(salt); - var encodedUrl = EncodeBase64URLSafeString(url); - var path = $"/rs:{resize}:{width}:{height}:{enlarge}/g:{gravity}/{encodedUrl}.{extension}"; - var passwordWithSaltBytes = new List(); passwordWithSaltBytes.AddRange(saltBin); passwordWithSaltBytes.AddRange(Encoding.UTF8.GetBytes(path)); diff --git a/examples/signature.dart b/examples/signature.dart index 7b9c6d30..986e829a 100644 --- a/examples/signature.dart +++ b/examples/signature.dart @@ -5,17 +5,8 @@ import 'package:crypto/crypto.dart'; void main() { var key = hex.decode("943b421c9eb07c830af81030552c86009268de4e532ba2ee2eab8247c6da0881"); var salt = hex.decode("520f986b998545b4785e0defbc4f3c1203f22de2374a3d53cb7a7fe9fea309c5"); - var url = "http://img.example.com/pretty/image.jpg"; - var resizing_type = 'fill'; - var width = 300; - var height = 300; - var gravity = 'no'; - var enlarge = 1; - var extension = 'png'; - var url_encoded = urlSafeBase64(utf8.encode(url)); - - var path = "/rs:$resizing_type:$width:$height:$enlarge/g:$gravity/$url_encoded.$extension"; + var path = "/rs:fit:300:300/plain/http://img.example.com/pretty/image.jpg"; var signature = sign(salt, utf8.encode(path), key); print("/$signature/$path"); diff --git a/examples/signature.ex b/examples/signature.ex index 838fac90..06ce75c2 100644 --- a/examples/signature.ex +++ b/examples/signature.ex @@ -1,22 +1,10 @@ defmodule App.Imgproxy do - @prefix "https://imgproxy.mybiz.xyz" @key Base.decode16!("943b421c9eb07c830af81030552c86009268de4e532ba2ee2eab8247c6da0881", case: :lower) @salt Base.decode16!("520f986b998545b4785e0defbc4f3c1203f22de2374a3d53cb7a7fe9fea309c5", case: :lower) - def build_url(img_url, opts) do - path = build_path(img_url, opts) + def sign_path(path) do signature = gen_signature(path) - - Path.join([@prefix, signature, path]) - end - - defp build_path(img_url, opts) do - Path.join([ - "/", - "rs:#{opts.resize}:#{opts.width}:#{opts.height}:#{opts.enlarge}", - "g:#{opts.gravity}", - Base.url_encode64(img_url, padding: false) <> "." <> opts.extension - ]) + Path.join(["/", signature, path]) end defp gen_signature(path) do @@ -28,7 +16,6 @@ end # Usage # -# App.Imgproxy.build_url( -# "https://myawesomedomain.com/raw-image.png", -# %{resize: "fit", width: 1000, height: 400, gravity: "ce", enlarge: 0, extension: "jpg"} +# App.Imgproxy.sign_path( +# "/rs:fit:300:300/plain/https://myawesomedomain.com/raw-image.png" # ) diff --git a/examples/signature.go b/examples/signature.go index 4f0254bd..7c31eb53 100644 --- a/examples/signature.go +++ b/examples/signature.go @@ -1,7 +1,4 @@ -//go:build exclude -// +build exclude - -package main +package examples import ( "crypto/hmac" @@ -12,32 +9,24 @@ import ( "log" ) -func main() { - key := "943b421c9eb07c830af81030552c86009268de4e532ba2ee2eab8247c6da0881" - salt := "520f986b998545b4785e0defbc4f3c1203f22de2374a3d53cb7a7fe9fea309c5" +const ( + key = "943b421c9eb07c830af81030552c86009268de4e532ba2ee2eab8247c6da0881" + salt = "520f986b998545b4785e0defbc4f3c1203f22de2374a3d53cb7a7fe9fea309c5" +) +func SignURL() { var keyBin, saltBin []byte var err error if keyBin, err = hex.DecodeString(key); err != nil { - log.Fatal("Key expected to be hex-encoded string") + log.Fatal(err) } if saltBin, err = hex.DecodeString(salt); err != nil { - log.Fatal("Salt expected to be hex-encoded string") + log.Fatal(err) } - resize := "fill" - width := 300 - height := 300 - gravity := "no" - enlarge := 1 - extension := "png" - - url := "http://img.example.com/pretty/image.jpg" - encodedURL := base64.RawURLEncoding.EncodeToString([]byte(url)) - - path := fmt.Sprintf("/rs:%s:%d:%d:%d/g:%s/%s.%s", resize, width, height, enlarge, gravity, encodedURL, extension) + path := "/rs:fit:300:300/plain/http://img.example.com/pretty/image.jpg" mac := hmac.New(sha256.New, keyBin) mac.Write(saltBin) diff --git a/examples/signature.java b/examples/signature.java index 04f70b3b..3d858488 100644 --- a/examples/signature.java +++ b/examples/signature.java @@ -15,26 +15,17 @@ public class ImgProxy{ public void testWithJavaHmacApacheBase64ImgProxyTest() throws Exception { byte[] key = hexStringToByteArray("943b421c9eb07c830af81030552c86009268de4e532ba2ee2eab8247c6da0881"); byte[] salt = hexStringToByteArray("520f986b998545b4785e0defbc4f3c1203f22de2374a3d53cb7a7fe9fea309c5"); - String url = "http://img.example.com/pretty/image.jpg"; - String resize = "fill"; - int width = 300; - int height = 300; - String gravity = "no"; - int enlarge = 1; - String extension = "png"; - String urlWithHash = generateSignedUrlForImgProxy(key, salt, url, resize, width, height, gravity, enlarge, extension); + String path = "/rs:fit:300:300/plain/http://img.example.com/pretty/image.jpg"; - assertEquals("/_PQ4ytCQMMp-1w1m_vP6g8Qb-Q7yF9mwghf6PddqxLw/fill/300/300/no/1/aHR0cDovL2ltZy5leGFtcGxlLmNvbS9wcmV0dHkvaW1hZ2UuanBn.png", urlWithHash); + String pathWithHash = signPath(key, salt, path); + + assertEquals("/m3k5QADfcKPDj-SDI2AIogZbC3FlAXszuwhtWXYqavc/rs:fit:300:300/plain/http://img.example.com/pretty/image.jp", pathWithHash); } - public static String generateSignedUrlForImgProxy(byte[] key, byte[] salt, String url, String resize, int width, int height, String gravity, int enlarge, String extension) throws Exception { + public static String signPath(byte[] key, byte[] salt, String path) throws Exception { final String HMACSHA256 = "HmacSHA256"; - String encodedUrl = Base64.getUrlEncoder().withoutPadding().encodeToString(url.getBytes()); - - String path = "/rs:" + resize + ":" + width + ":" + height + ":" + enlarge + "/g:" + gravity + "/" + encodedUrl + "." + extension; - Mac sha256HMAC = Mac.getInstance(HMACSHA256); SecretKeySpec secretKey = new SecretKeySpec(key, HMACSHA256); sha256HMAC.init(secretKey); diff --git a/examples/signature.js b/examples/signature.js index 895bfd69..ecbbce75 100644 --- a/examples/signature.js +++ b/examples/signature.js @@ -16,15 +16,7 @@ const sign = (salt, target, secret) => { return urlSafeBase64(hmac.digest()) } -const url = 'http://img.example.com/pretty/image.jpg' -const resizing_type = 'fill' -const width = 300 -const height = 300 -const gravity = 'no' -const enlarge = 1 -const extension = 'png' -const encoded_url = urlSafeBase64(url) -const path = `/rs:${resizing_type}:${width}:${height}:${enlarge}/g:${gravity}/${encoded_url}.${extension}` +const path = "/rs:fit:300:300/plain/http://img.example.com/pretty/image.jpg" const signature = sign(SALT, path, KEY) const result = `/${signature}${path}` diff --git a/examples/signature.php b/examples/signature.php index 2d469269..2179639e 100644 --- a/examples/signature.php +++ b/examples/signature.php @@ -13,17 +13,7 @@ if(empty($saltBin)) { die('Salt expected to be hex-encoded string'); } -$resize = 'fill'; -$width = 300; -$height = 300; -$gravity = 'no'; -$enlarge = 1; -$extension = 'png'; - -$url = 'http://img.example.com/pretty/image.jpg'; -$encodedUrl = rtrim(strtr(base64_encode($url), '+/', '-_'), '='); - -$path = "/rs:{$resize}:{$width}:{$height}:{$enlarge}/g:{$gravity}/{$encodedUrl}.{$extension}"; +$path = "/rs:fit:300:300/plain/http://img.example.com/pretty/image.jpg"; $signature = rtrim(strtr(base64_encode(hash_hmac('sha256', $saltBin.$path, $keyBin, true)), '+/', '-_'), '='); diff --git a/examples/signature.py b/examples/signature.py index abf442a1..7e30efb1 100644 --- a/examples/signature.py +++ b/examples/signature.py @@ -1,41 +1,20 @@ import base64 import hashlib import hmac -import textwrap key = bytes.fromhex("943b421c9eb07c830af81030552c86009268de4e532ba2ee2eab8247c6da0881") salt = bytes.fromhex("520f986b998545b4785e0defbc4f3c1203f22de2374a3d53cb7a7fe9fea309c5") -url = b"http://img.example.com/pretty/image.jpg" +path = "/rs:fit:300:300/plain/http://img.example.com/pretty/image.jpg".encode() -encoded_url = base64.urlsafe_b64encode(url).rstrip(b"=").decode() -# You can trim padding spaces to get good-looking url -encoded_url = '/'.join(textwrap.wrap(encoded_url, 16)) - -path = "/rs:{resize}:{width}:{height}:{enlarge}/g:{gravity}/{encoded_url}.{extension}".format( - encoded_url=encoded_url, - resize="fill", - width=300, - height=300, - gravity="no", - enlarge=1, - extension="png", -).encode() digest = hmac.new(key, msg=salt+path, digestmod=hashlib.sha256).digest() - -protection = base64.urlsafe_b64encode(digest).rstrip(b"=") +signature = base64.urlsafe_b64encode(digest).rstrip(b"=") url = b'/%s%s' % ( - protection, + signature, path, ) print(url.decode()) - -# without / in url -# /_PQ4ytCQMMp-1w1m_vP6g8Qb-Q7yF9mwghf6PddqxLw/fill/300/300/no/1/aHR0cDovL2ltZy5leGFtcGxlLmNvbS9wcmV0dHkvaW1hZ2UuanBn.png - -# with / in url -# /MlF9VpgaHqcmVK3FyT9CTJhfm0rfY6JKnAtxoiAX9t0/fill/300/300/no/1/aHR0cDovL2ltZy5l/eGFtcGxlLmNvbS9w/cmV0dHkvaW1hZ2Uu/anBn.png diff --git a/examples/signature.rb b/examples/signature.rb index 9759bf68..453a5bc3 100644 --- a/examples/signature.rb +++ b/examples/signature.rb @@ -4,22 +4,11 @@ require "base64" key = ["943b421c9eb07c830af81030552c86009268de4e532ba2ee2eab8247c6da0881"].pack("H*") salt = ["520f986b998545b4785e0defbc4f3c1203f22de2374a3d53cb7a7fe9fea309c5"].pack("H*") -url = "http://img.example.com/pretty/image.jpg" - -# You can trim padding spaces to get good-looking url -encoded_url = Base64.urlsafe_encode64(url).tr("=", "").scan(/.{1,16}/).join("/") - -resize = "fill" -width = 300 -height = 300 -gravity = "no" -enlarge = 1 -extension = "png" - -path = "/rs:#{resize}:#{width}:#{height}:#{enlarge}/g:#{gravity}/#{encoded_url}.#{extension}" +path = "/rs:fit:300:300/plain/http://img.example.com/pretty/image.jpg" digest = OpenSSL::Digest.new("sha256") # You can trim padding spaces to get good-looking url hmac = Base64.urlsafe_encode64(OpenSSL::HMAC.digest(digest, key, "#{salt}#{path}")).tr("=", "") signed_path = "/#{hmac}#{path}" +puts signed_path diff --git a/examples/signature.rs b/examples/signature.rs index f9f3463c..156b2a87 100644 --- a/examples/signature.rs +++ b/examples/signature.rs @@ -2,7 +2,7 @@ use std::process; use base64; // https://crates.io/crates/base64 use hex::{self, FromHexError}; // https://crates.io/crates/hex -use hmac::{Hmac, Mac, NewMac}; // https://crates.io/crates/hmac +use hmac::{Hmac, Mac}; // https://crates.io/crates/hmac use sha2::Sha256; // https://crates.io/crates/sha2 type HmacSha256 = Hmac; @@ -25,16 +25,11 @@ pub enum Error { } fn main() { - let img = Image { - src: "http://img.example.com/pretty/image.jpg", - width: 100, - height: 80, - dpr: 2, - ext: "webp", - }; - match sign_url(img) { - Ok(url) => { - println!("{}", url); + let path = "/rs:fit:300:300/plain/http://img.example.com/pretty/image.jpg"; + + match sign_path(path) { + Ok(signed_path) => { + println!("{}", signed_path); process::exit(0); } Err(err) => { @@ -44,18 +39,7 @@ fn main() { } } -pub fn sign_url(img: Image) -> Result { - let url = format!( - "/rs:{resize_type}:{width}:{height}:{enlarge}:{extend}/dpr:{dpr}/{src}.{ext}", - resize_type = "auto", - width = img.width, - height = img.height, - enlarge = 0, - extend = 0, - dpr = img.dpr, - src = base64::encode_config(img.src.as_bytes(), base64::URL_SAFE_NO_PAD), - ext = img.ext, - ); +pub fn sign_path(path: &str) -> Result { let decoded_key = match hex::decode(KEY) { Ok(key) => key, Err(err) => return Err(Error::InvalidKey(err)), @@ -64,12 +48,15 @@ pub fn sign_url(img: Image) -> Result { Ok(salt) => salt, Err(err) => return Err(Error::InvalidSalt(err)), }; - let mut hmac = HmacSha256::new_varkey(&decoded_key).unwrap(); + + let mut hmac = HmacSha256::new_from_slice(&decoded_key).unwrap(); hmac.update(&decoded_salt); - hmac.update(url.as_bytes()); + hmac.update(path.as_bytes()); + let signature = hmac.finalize().into_bytes(); let signature = base64::encode_config(signature.as_slice(), base64::URL_SAFE_NO_PAD); - let signed_url = format!("/{signature}{url}", signature = signature, url = url); - Ok(signed_url) + let signed_path = format!("/{}{}", signature, path); + + Ok(signed_path) } diff --git a/examples/signature.swift b/examples/signature.swift index 86ac22fc..830f279b 100644 --- a/examples/signature.swift +++ b/examples/signature.swift @@ -46,17 +46,7 @@ func customBase64(input: Data) -> String { let key = "943b421c9eb07c830af81030552c86009268de4e532ba2ee2eab8247c6da0881".hexadecimal()!; let salt = "520f986b998545b4785e0defbc4f3c1203f22de2374a3d53cb7a7fe9fea309c5".hexadecimal()!; -let resizing = "fill"; -let width = 300; -let height = 300; -let gravity = "no"; -let enlarge = 1; -let originalUrl = "http://img.example.com/pretty/image.jpg"; - -let encodedUrl = customBase64(input: Data(originalUrl.utf8)) -let format = "png"; - -let partialPath = "/rs:\(resizing):\(width):\(height):\(enlarge)/g:\(gravity)/\(encodedUrl).\(format)" +let partialPath = "/rs:fit:300:300/plain/http://img.example.com/pretty/image.jpg" let toSign = salt + partialPath.utf8 let signature = toSign.hmac256(key: key)