steganography Go Library

repository·main·Indexed 43 days ago

https://github.com/auyer/steganography

A pure Go library for performing Least Significant Bit (LSB) steganography on images, allowing users to hide and retrieve any file format within an image. It includes a CLI tool for encoding and decoding PNG files and provides programmatic functions such as Encode, Decode, and GetMessageSizeFromImage.

Tokens
2.3K
Snippets
12
Records
12
Agent score
55%

What's inside steganography

  1. Encode a message into a PNG file

    main

    To hide a message from a text file inside a PNG image, use the -e flag. You must provide the input image path with -i, the path to the message text file with -mi, and the desired output image path with -o.

    go run stego.go -e -i stegosaurus.png -mi message.txt -o encoded_stegosaurus.png
  2. Encode a message into an image

    main

    Use steganography.Encode to embed a byte slice (message) into an existing image.Image. The encoded data is written to an io.Writer (such as a bytes.Buffer or an os.File).

    Capacity Note: The minimum image size required is 24 pixels for a single byte. For every additional byte, you need 3 more pixels.

    w := new(bytes.Buffer)
    err := steganography.Encode(w, img, []byte("message"))
    if err != nil {
        log.Printf("Error Encoding file %v", err)
        return
    }
    // To save the result, write the buffer to a file
    outFile, _ := os.Create("out_file.png")
    w.WriteTo(outFile)
    outFile.Close()
  3. Decode a message from an image

    main

    To extract a hidden message from an image, first determine the message size using steganography.GetMessageSizeFromImage, then pass that size and the image to steganography.Decode.

    // 1. Decode the image from a file
    inFile, _ := os.Open(encodedInputFile)
    defer inFile.Close()
    reader := bufio.NewReader(inFile)
    img, _ := png.Decode(reader)
    
    // 2. Retrieve the message size
    sizeOfMessage := steganography.GetMessageSizeFromImage(img)
    
    // 3. Decode the message
    msg := steganography.Decode(sizeOfMessage, img)
    fmt.Println(string(msg))
  4. Determine the maximum message size from an image

    main

    Use steganography.GetMessageSizeFromImage to perform a preliminary check on a carrier image. This allows you to deduce how large a hidden message or file the image can store before attempting to encode or decode.

    sizeOfMessage := steganography.GetMessageSizeFromImage(img) // retrieves the size of the encoded message
  5. Use the stego.go CLI

    main

    The stego.go CLI tool provides flags for encoding and decoding messages within PNG images.

    Flags:

    • -help: Shows the usage message.
    • -d: Enables decoding mode to extract a message from a PNG file.
    • -e: Enables encoding mode to hide a message in a PNG file.
    • -i string: Path to the input image.
    • -mi string: Path to the input message file (required for encoding).
    • -mo string: Path to the message output file.
    • -o string: Path to the output image (defaults to encoded.png).
    Usage stego.go
    
        -help 	Will show this message below
    
        -d	Specifies if you would like to decode a message from a given PNG file
    
        -e 	Specifies if you would like to encode a message to a given PNG file
    
        -i string Path to the the input image
    
        -mi string Path to the message input file
        
        -mo string Path to the message output file
        
        -o string Path to the the output image (default "encoded.png")
  6. Calculate the maximum message size with MaxEncodeSize

    main

    Use MaxEncodeSize to determine the maximum number of bytes that can be safely encoded into a given image using LSB steganography. This calculation accounts for the 4-byte header used to store the message length.

    Formula used: ((width * height * 3) / 8) - 4

    Returns:

    • uint32: The maximum number of bytes available for the message payload.
    package main
    
    import (
    	"image"
    	""steganography"
    )
    
    func main() {
    	var img image.Image
    	maxSize := steganography.MaxEncodeSize(img)
    	// maxSize is the maximum payload length in bytes
    }
  7. Decode a message from an image using Decode

    main

    Use Decode to extract a secret message from an image that was encoded using this library. You must provide the expected length of the message.

    Inputs:

    • msgLen uint32: The number of bytes to decode from the image.
    • pictureInputFile image.Image: The image containing the encoded message.

    Returns:

    • []byte: The decoded message as a byte slice.
    package main
    
    import (
    	"image"
    	""steganography"
    )
    
    func main() {
    	// Assume img is an image.Image loaded from a file
    	var img image.Image
    	msgLen := uint32(15)
    
    	message := steganography.Decode(msgLen, img)
    	// message contains the decoded bytes
    }
  8. Retrieve message size from an encoded image with GetMessageSizeFromImage

    main

    If you have an image that was encoded with this library but you do not know the length of the hidden message, use GetMessageSizeFromImage. It reads the first 4 bytes of the encoded data (the header) to determine the message length.

    Input:

    • pictureInputFile image.Image: The image containing the encoded message.

    Returns:

    • uint32: The size of the encoded message in bytes.
    package main
    
    import (
    	"image"
    	""steganography"
    )
    
    func main() {
    	var img image.Image
    	size := steganography.GetMessageSizeFromImage(img)
    	// size is the length needed for Decode(size, img)
    }
  9. Encode a message into an NRGBA image using EncodeNRGBA

    main

    Use EncodeNRGBA when you are working specifically with *image.NRGBA types. This is the low-level implementation used by Encode.

    Inputs:

    • writeBuffer *bytes.Buffer: Destination for the encoded PNG bytes.
    • rgbImage *image.NRGBA: The specific NRGBA image to modify.
    • message []byte: The secret message.

    Returns:

    • error: Returns an error if the message is too large or encoding fails.
    package main
    
    import (
    	"bytes"
    	"image"
    	""steganography"
    )
    
    func main() {
    	// Assume rgbImg is an *image.NRGBA
    	rgbImg := &image.NRGBA{}
    	message := []byte("secret")
    	writeBuffer := new(bytes.Buffer)
    
    	err := steganography.EncodeNRGBA(writeBuffer, rgbImg, message)
    	if err != nil {
    		panic(err)
    	}
    }
  10. Encode a message into an image using Encode

    main

    Use Encode to hide a byte slice ([]byte) within an image. The function uses Least Significant Bit (LSB) steganography. It automatically handles the conversion of the input image.Image to image.NRGBA and prepends a 4-byte header representing the message length.

    Inputs:

    • writeBuffer *bytes.Buffer: The destination buffer where the resulting encoded PNG image bytes will be written.
    • pictureInputFile image.Image: The source image used as the carrier.
    • message []byte: The secret message to encode.

    Returns:

    • error: Returns an error if the message is too large for the provided image or if PNG encoding fails.
    package main
    
    import (
    	"bytes"
    	"image"
    	""steganography"
    )
    
    func main() {
    	// Assume img is an existing image.Image
    	var img image.Image
    	message := []byte("secret message")
    	writeBuffer := new(bytes.Buffer)
    
    	err := steganography.Encode(writeBuffer, img, message)
    	if err != nil {
    		panic(err)
    	}
    	// writeBuffer now contains the PNG bytes of the encoded image
    }