| 19 | } |
| 20 | |
| 21 | func ExcryptSourceURL() { |
| 22 | key := "1eb5b0e971ad7f45324c1bb15c947cb207c43152fa5c6c7f35c4f36e0c18e0f1" |
| 23 | |
| 24 | var ( |
| 25 | keyBin []byte |
| 26 | err error |
| 27 | ) |
| 28 | |
| 29 | if keyBin, err = hex.DecodeString(key); err != nil { |
| 30 | log.Fatal("Key expected to be hex-encoded string") |
| 31 | } |
| 32 | |
| 33 | url := "http://img.example.com/pretty/image.jpg" |
| 34 | |
| 35 | c, err := aes.NewCipher(keyBin) |
| 36 | if err != nil { |
| 37 | log.Fatal(err) |
| 38 | } |
| 39 | |
| 40 | data := pkcs7pad([]byte(url), aes.BlockSize) |
| 41 | |
| 42 | ciphertext := make([]byte, aes.BlockSize+len(data)) |
| 43 | iv := ciphertext[:aes.BlockSize] |
| 44 | |
| 45 | // We use a random iv generation, but you'll probably want to use some |
| 46 | // deterministic method |
| 47 | if _, err = io.ReadFull(rand.Reader, iv); err != nil { |
| 48 | log.Fatal(err) |
| 49 | } |
| 50 | |
| 51 | mode := cipher.NewCBCEncrypter(c, iv) |
| 52 | mode.CryptBlocks(ciphertext[aes.BlockSize:], data) |
| 53 | |
| 54 | encryptedURL := base64.RawURLEncoding.EncodeToString(ciphertext) |
| 55 | |
| 56 | // We don't sign the URL in this example but it is highly recommended to sign |
| 57 | // imgproxy URLs when imgproxy is being used in production. |
| 58 | // Signing URLs is especially important when using encrypted source URLs to |
| 59 | // prevent a padding oracle attack |
| 60 | fmt.Printf("/unsafe/rs:fit:300:300/enc/%s.jpg", encryptedURL) |
| 61 | } |