refactor(crypto): use IV as a constant

This commit is contained in:
Mathis Maquenne
2025-05-07 20:57:12 +02:00
parent 67af80403b
commit ebfb312718
4 changed files with 13 additions and 26 deletions
-2
View File
@@ -1,4 +1,2 @@
arl_cookie = '1d9e90abb452a61b1b7463f0953e1b303c4e2e7e5fd404fde9b385f4de01c340ac0f62f1c8c1550405b0b9beded0e28c481e96a6148e8f4548351add5d7db746b2785ecf83b1768e5dd8cc73b1ad30c18d07c9cb37f5c6b9cd7a78a4de2aff11' arl_cookie = '1d9e90abb452a61b1b7463f0953e1b303c4e2e7e5fd404fde9b385f4de01c340ac0f62f1c8c1550405b0b9beded0e28c481e96a6148e8f4548351add5d7db746b2785ecf83b1768e5dd8cc73b1ad30c18d07c9cb37f5c6b9cd7a78a4de2aff11'
license_token = 'AAAAA1bcDFgHJKLmnOPqrsTUvwXYZ12o3lmNOjR2xWiQRT3v5zxL4mKoWjxL82jD7sWx93KfYGsN2IkdPxsUw9PTas7oFbgR3nY9qpZmVyHFJKLPxT7sWmqErXyTn5iKoNpRtV7bPdQZ8qLmWoJpU2nKrXz6vW'
secret_key = 'hTv1IAw19qWy9i3f' secret_key = 'hTv1IAw19qWy9i3f'
iv = '0001020304050607'
+1 -8
View File
@@ -11,7 +11,6 @@ import (
type Config struct { type Config struct {
ArlCookie string `mapstructure:"arl_cookie"` ArlCookie string `mapstructure:"arl_cookie"`
SecretKey string `mapstructure:"secret_key"` SecretKey string `mapstructure:"secret_key"`
IV string `mapstructure:"iv"`
} }
func New(cfgPath, cfgDir string) (*Config, error) { func New(cfgPath, cfgDir string) (*Config, error) {
@@ -22,7 +21,7 @@ func New(cfgPath, cfgDir string) (*Config, error) {
if _, err := os.Stat(cfgPath); os.IsNotExist(err) { if _, err := os.Stat(cfgPath); os.IsNotExist(err) {
fmt.Printf("Config file not found, creating one at %s\n", cfgPath) fmt.Printf("Config file not found, creating one at %s\n", cfgPath)
content := []byte("arl_cookie = ''\nsecret_key = ''\niv = '0001020304050607'\n") content := []byte("arl_cookie = ''\nsecret_key = ''\n")
if err := os.WriteFile(cfgPath, content, 0644); err != nil { if err := os.WriteFile(cfgPath, content, 0644); err != nil {
return nil, fmt.Errorf("failed to create config file: %w", err) return nil, fmt.Errorf("failed to create config file: %w", err)
} }
@@ -52,12 +51,6 @@ func New(cfgPath, cfgDir string) (*Config, error) {
if len(cfg.SecretKey) != 16 { if len(cfg.SecretKey) != 16 {
return nil, fmt.Errorf("secret_key must be 16 bytes long") return nil, fmt.Errorf("secret_key must be 16 bytes long")
} }
if cfg.IV == "" {
return nil, fmt.Errorf("iv is not set in config file")
}
if len(cfg.IV) != 16 {
return nil, fmt.Errorf("iv must be 16 bytes long")
}
return cfg, nil return cfg, nil
} }
+3 -1
View File
@@ -8,6 +8,8 @@ import (
"golang.org/x/crypto/blowfish" "golang.org/x/crypto/blowfish"
) )
var iv = []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}
func GetKey(secretKey, songID string) []byte { func GetKey(secretKey, songID string) []byte {
hash := md5.Sum([]byte(songID)) hash := md5.Sum([]byte(songID))
hashHex := fmt.Sprintf("%x", hash) hashHex := fmt.Sprintf("%x", hash)
@@ -20,7 +22,7 @@ func GetKey(secretKey, songID string) []byte {
return key return key
} }
func Decrypt(data, key, iv []byte) ([]byte, error) { func Decrypt(data, key []byte) ([]byte, error) {
block, err := blowfish.NewCipher(key) block, err := blowfish.NewCipher(key)
if err != nil { if err != nil {
return nil, err return nil, err
+9 -15
View File
@@ -2,7 +2,6 @@ package downloader
import ( import (
"context" "context"
"encoding/hex"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@@ -20,7 +19,7 @@ import (
"github.com/mathismqn/godeez/internal/tags" "github.com/mathismqn/godeez/internal/tags"
) )
const ChunkSize = 2048 const chunkSize = 2048
type Client struct { type Client struct {
appCtx *app.Context appCtx *app.Context
@@ -135,7 +134,8 @@ func (c *Client) downloadSong(ctx context.Context, resource deezer.Resource, son
dlCtx, cancel := context.WithTimeout(ctx, opts.Timeout) dlCtx, cancel := context.WithTimeout(ctx, opts.Timeout)
defer cancel() defer cancel()
if err := c.streamToFile(dlCtx, stream, outputPath, song.ID); err != nil { key := crypto.GetKey(c.appCtx.Config.SecretKey, song.ID)
if err := c.streamToFile(dlCtx, stream, outputPath, key); err != nil {
fileutil.DeleteFile(outputPath) fileutil.DeleteFile(outputPath)
return fmt.Errorf("unable to write to file: %w", err) return fmt.Errorf("unable to write to file: %w", err)
@@ -180,7 +180,7 @@ func (c *Client) shouldSkipDownload(ctx context.Context, songID, mediaFormat str
return "", false return "", false
} }
func (c *Client) streamToFile(ctx context.Context, stream io.ReadCloser, outputPath, songID string) error { func (c *Client) streamToFile(ctx context.Context, stream io.ReadCloser, outputPath string, key []byte) error {
defer stream.Close() defer stream.Close()
file, err := os.Create(outputPath) file, err := os.Create(outputPath)
@@ -189,13 +189,7 @@ func (c *Client) streamToFile(ctx context.Context, stream io.ReadCloser, outputP
} }
defer file.Close() defer file.Close()
key := crypto.GetKey(c.appCtx.Config.SecretKey, songID) buffer := make([]byte, chunkSize)
iv, err := hex.DecodeString(c.appCtx.Config.IV)
if err != nil {
return err
}
buffer := make([]byte, ChunkSize)
for chunk := 0; ; chunk++ { for chunk := 0; ; chunk++ {
select { select {
case <-ctx.Done(): case <-ctx.Done():
@@ -205,7 +199,7 @@ func (c *Client) streamToFile(ctx context.Context, stream io.ReadCloser, outputP
} }
totalRead := 0 totalRead := 0
for totalRead < ChunkSize { for totalRead < chunkSize {
n, err := stream.Read(buffer[totalRead:]) n, err := stream.Read(buffer[totalRead:])
if err != nil { if err != nil {
if errors.Is(err, io.EOF) { if errors.Is(err, io.EOF) {
@@ -223,8 +217,8 @@ func (c *Client) streamToFile(ctx context.Context, stream io.ReadCloser, outputP
break break
} }
if chunk%3 == 0 && totalRead == ChunkSize { if chunk%3 == 0 && totalRead == chunkSize {
buffer, err = crypto.Decrypt(buffer, key, iv) buffer, err = crypto.Decrypt(buffer, key)
if err != nil { if err != nil {
return err return err
} }
@@ -235,7 +229,7 @@ func (c *Client) streamToFile(ctx context.Context, stream io.ReadCloser, outputP
return err return err
} }
if totalRead < ChunkSize { if totalRead < chunkSize {
break break
} }
} }