steganon


Namesteganon JSON
Version 0.2 PyPI version JSON
download
home_pagehttps://github.com/NonProjects/steganon
SummarySteganography LSB (with PRNG by seed)
upload_time2024-02-01 17:22:18
maintainer
docs_urlNone
authorNonProjects
requires_python
licenseLGPL-2.1
keywords steganography lsb cryptography
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # SteganoN

**Steganon** is an extended implementation of the [LSB steganography algorithm](https://www.google.com/search?q=LSB+steganography+algorithm).

In short, steganography **LSB** is a method of hiding data inside pixels of image. Every pixel of an image consist of three integers (**0-255**, or **one byte**). They describe an amount of **R**ed, **G**reen and **B**lue colors. We take User's data to hide and convert it to a **bit string**; then we take next target pixel and select first integer: **R**. We convert this integer into bit string and change it's [least significant bit](https://en.wikipedia.org/wiki/Bit_numbering) to the next bit of User's data. Repeat this process for **G** and **B** then write altered pixel back into image. Repeat until User's data is not empty. Such change to **RGB** is invisible to human eye and gives us chance to hide **three bits** of data **per pixel** (three pixels per byte).

## Difference between classic LSB and LSB_WS


This repository implements a different type of LSB: **LSB With [Seed](https://en.wikipedia.org/wiki/Random_seed)** (short. `LSB_WS`). This is a (designed by [**me**](https://github.com/NotStatilko)) subclass of LSB that is use [**PRNG**](https://en.wikipedia.org/wiki/Pseudorandom_number_generator) with changeable [seed](https://en.wikipedia.org/wiki/Random_seed) to determine targeted pixels. Here, *Seed* acts like password. You must know it to extract any hidden data, and fact that image contains any hidden data is more obscure. I believe that `LSB_WS` is more strong against any [analyze](https://www.google.com/search?q=how+to+crack+lsb+stegano).

## Installation

**You can install SteganoN from PIP**
```bash
pip install steganon
```
**Or you can install with git clone**
```bash
python -m venv steganon-env
cd steganon-env && . bin/activate

git clone https://github.com/NonProjects/steganon
pip install ./steganon
```

## Example

### Hiding Secret Data

```python3
from steganon import Image, LSB_WS

image = Image.open('example.png') # Open targeted Image
lsb_ws = LSB_WS(image, b'seed_0') # Init with seed=b'seed_0'

lsb_ws.hide(b'Secret!!!') # Write secret message to image pixels
image.save('example.png') # Save altered image with secret data
```
#### Under the hood (Pseudo-code)
```python
# Pseudo-code here! See source file for exact implementation

image = Image.open('example.png')

secret, seed = 'Secret!!!', b'seed_0'
secret_bin = binary(secret) = list('010100110110010101100011011100100110010101110100001000010010000100100001')

prng = PRNG(seed) # In reality we use Python's random module, which is Mersenne Twister

while secret_bin:
    # In the actual code we store position of pixels that we changed, so
    # if "random_pixel" will return us pixel that already been altered
    # we will request next position, up until we will not find empty one
    next_pixel = image.get_pixel(prng.random_pixel(image)) # (255, 0, 0)

    # Also, as there is three integers per pixel and only eight bits
    # per byte of secret data we add zero (0) to start of every bits of
    # byte of secret data so it's total size will be 9 and we can
    # easily hide whole byte of secret data in three pixels. In this
    # pseudo-code example this is ignored. 11111111 will be 011111111.

    new_pixel = []
    for color_integer in next_pixel:
        color_bits = binary(color_integer) # 255 = 11111111 (First Iteration)
        color_bits[-1] = secret_bin.pop(0) # color_bits ~= 11111110 (First Iteration)
        new_pixel.append(binary_to_int(color_bits)) # 11111110 = 254 (First Iteration)

    image.put_pixel(new_pixel) # [254, 1, 0] (After all Iterations)
```
### Extracting Secret Data
```python
# Secret Data extraction schema is pretty the same as hide process,
# the only difference is that we only take last significant byte

from steganon import Image, LSB_WS

image = Image.open('example.png') # Opening Image with hidden data
lsb_ws = LSB_WS(image, b'seed_0') # Init with seed=b'seed_0'

print(lsb_ws.extract()) # b'Secret!!!'
```

## Image Comparison

Here is comparison between [**Original image (1)**](https://github.com/NonProjects/steganon/assets/43419673/4f0f7238-f51e-45c5-80b0-3e039b26c8de) and [**Image with written on pixels data (2)**](https://github.com/NonProjects/steganon/assets/43419673/ddc67292-d085-47dc-ae04-2dd131496899).

<img src="https://github.com/NonProjects/steganon/assets/43419673/45e529b6-c45a-454c-bbf3-8426ba9dd9f5" width="777" height="-1"></img>

[**Modified Image (2)**](https://github.com/NonProjects/steganon/assets/43419673/ddc67292-d085-47dc-ae04-2dd131496899) has whole [**Zen of Python**](https://peps.python.org/pep-0020/#the-zen-of-python) written on it.\
You can extract Zen from **(2)** by using Seed `b'spam_eggs'`

## TestMode on LSB_WS

`steganon.LSB_WS` class has a `testmode` key. We can use it to check affected pixels under different seeds

<img src="https://github.com/NonProjects/steganon/assets/43419673/91d0c920-2749-4a5d-afa1-b43d76b29aa0" width="777" height="-1"></img>

## Additional Information

0. **Always use a different seed!** Pixel positions will be the same on different images and text!
1. All of this developed by me and currently **wasn't** verified by cryptography experts. Use with caution!
2. `hide()` process can be long on big Data and small image. Note: **one byte of data is 3 pixels**;
3. This library **will not** work with JPEG. PNG is OK and recommended. Other formats need testing;
4. Best template to hide data is a compressed JPEG turned to PNG. Library have `tools.pngify`, use it.

Contact me on thenonproton@pm.me (or just open Issue) if you have any feedback on this library.

## All Aboard!

Try to download [**this example image**](https://github.com/NonProjects/steganon/assets/43419673/2b13ef7c-b37f-4d4f-a88f-7b035324a905) and extract secret data from it (may take some time :)\
Seed is `b'OZZY'`, save data to the file with `.ogg` extension and play with your media player

###### Crazy? But that's how it goes!

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/NonProjects/steganon",
    "name": "steganon",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "Steganography,LSB,Cryptography",
    "author": "NonProjects",
    "author_email": "thenonproton@pm.me",
    "download_url": "https://files.pythonhosted.org/packages/e9/59/aa0926f34a268a74fa9e23b78e3d931dc5dc1e40e09b20993f30dbb75f28/steganon-0.2.tar.gz",
    "platform": null,
    "description": "# SteganoN\n\n**Steganon** is an extended implementation of the [LSB steganography algorithm](https://www.google.com/search?q=LSB+steganography+algorithm).\n\nIn short, steganography **LSB** is a method of hiding data inside pixels of image. Every pixel of an image consist of three integers (**0-255**, or **one byte**). They describe an amount of **R**ed, **G**reen and **B**lue colors. We take User's data to hide and convert it to a **bit string**; then we take next target pixel and select first integer: **R**. We convert this integer into bit string and change it's [least significant bit](https://en.wikipedia.org/wiki/Bit_numbering) to the next bit of User's data. Repeat this process for **G** and **B** then write altered pixel back into image. Repeat until User's data is not empty. Such change to **RGB** is invisible to human eye and gives us chance to hide **three bits** of data **per pixel** (three pixels per byte).\n\n## Difference between classic LSB and LSB_WS\n\n\nThis repository implements a different type of LSB: **LSB With [Seed](https://en.wikipedia.org/wiki/Random_seed)** (short. `LSB_WS`). This is a (designed by [**me**](https://github.com/NotStatilko)) subclass of LSB that is use [**PRNG**](https://en.wikipedia.org/wiki/Pseudorandom_number_generator) with changeable [seed](https://en.wikipedia.org/wiki/Random_seed) to determine targeted pixels. Here, *Seed* acts like password. You must know it to extract any hidden data, and fact that image contains any hidden data is more obscure. I believe that `LSB_WS` is more strong against any [analyze](https://www.google.com/search?q=how+to+crack+lsb+stegano).\n\n## Installation\n\n**You can install SteganoN from PIP**\n```bash\npip install steganon\n```\n**Or you can install with git clone**\n```bash\npython -m venv steganon-env\ncd steganon-env && . bin/activate\n\ngit clone https://github.com/NonProjects/steganon\npip install ./steganon\n```\n\n## Example\n\n### Hiding Secret Data\n\n```python3\nfrom steganon import Image, LSB_WS\n\nimage = Image.open('example.png') # Open targeted Image\nlsb_ws = LSB_WS(image, b'seed_0') # Init with seed=b'seed_0'\n\nlsb_ws.hide(b'Secret!!!') # Write secret message to image pixels\nimage.save('example.png') # Save altered image with secret data\n```\n#### Under the hood (Pseudo-code)\n```python\n# Pseudo-code here! See source file for exact implementation\n\nimage = Image.open('example.png')\n\nsecret, seed = 'Secret!!!', b'seed_0'\nsecret_bin = binary(secret) = list('010100110110010101100011011100100110010101110100001000010010000100100001')\n\nprng = PRNG(seed) # In reality we use Python's random module, which is Mersenne Twister\n\nwhile secret_bin:\n    # In the actual code we store position of pixels that we changed, so\n    # if \"random_pixel\" will return us pixel that already been altered\n    # we will request next position, up until we will not find empty one\n    next_pixel = image.get_pixel(prng.random_pixel(image)) # (255, 0, 0)\n\n    # Also, as there is three integers per pixel and only eight bits\n    # per byte of secret data we add zero (0) to start of every bits of\n    # byte of secret data so it's total size will be 9 and we can\n    # easily hide whole byte of secret data in three pixels. In this\n    # pseudo-code example this is ignored. 11111111 will be 011111111.\n\n    new_pixel = []\n    for color_integer in next_pixel:\n        color_bits = binary(color_integer) # 255 = 11111111 (First Iteration)\n        color_bits[-1] = secret_bin.pop(0) # color_bits ~= 11111110 (First Iteration)\n        new_pixel.append(binary_to_int(color_bits)) # 11111110 = 254 (First Iteration)\n\n    image.put_pixel(new_pixel) # [254, 1, 0] (After all Iterations)\n```\n### Extracting Secret Data\n```python\n# Secret Data extraction schema is pretty the same as hide process,\n# the only difference is that we only take last significant byte\n\nfrom steganon import Image, LSB_WS\n\nimage = Image.open('example.png') # Opening Image with hidden data\nlsb_ws = LSB_WS(image, b'seed_0') # Init with seed=b'seed_0'\n\nprint(lsb_ws.extract()) # b'Secret!!!'\n```\n\n## Image Comparison\n\nHere is comparison between [**Original image (1)**](https://github.com/NonProjects/steganon/assets/43419673/4f0f7238-f51e-45c5-80b0-3e039b26c8de) and [**Image with written on pixels data (2)**](https://github.com/NonProjects/steganon/assets/43419673/ddc67292-d085-47dc-ae04-2dd131496899).\n\n<img src=\"https://github.com/NonProjects/steganon/assets/43419673/45e529b6-c45a-454c-bbf3-8426ba9dd9f5\" width=\"777\" height=\"-1\"></img>\n\n[**Modified Image (2)**](https://github.com/NonProjects/steganon/assets/43419673/ddc67292-d085-47dc-ae04-2dd131496899) has whole [**Zen of Python**](https://peps.python.org/pep-0020/#the-zen-of-python) written on it.\\\nYou can extract Zen from **(2)** by using Seed `b'spam_eggs'`\n\n## TestMode on LSB_WS\n\n`steganon.LSB_WS` class has a `testmode` key. We can use it to check affected pixels under different seeds\n\n<img src=\"https://github.com/NonProjects/steganon/assets/43419673/91d0c920-2749-4a5d-afa1-b43d76b29aa0\" width=\"777\" height=\"-1\"></img>\n\n## Additional Information\n\n0. **Always use a different seed!** Pixel positions will be the same on different images and text!\n1. All of this developed by me and currently **wasn't** verified by cryptography experts. Use with caution!\n2. `hide()` process can be long on big Data and small image. Note: **one byte of data is 3 pixels**;\n3. This library **will not** work with JPEG. PNG is OK and recommended. Other formats need testing;\n4. Best template to hide data is a compressed JPEG turned to PNG. Library have `tools.pngify`, use it.\n\nContact me on thenonproton@pm.me (or just open Issue) if you have any feedback on this library.\n\n## All Aboard!\n\nTry to download [**this example image**](https://github.com/NonProjects/steganon/assets/43419673/2b13ef7c-b37f-4d4f-a88f-7b035324a905) and extract secret data from it (may take some time :)\\\nSeed is `b'OZZY'`, save data to the file with `.ogg` extension and play with your media player\n\n###### Crazy? But that's how it goes!\n",
    "bugtrack_url": null,
    "license": "LGPL-2.1",
    "summary": "Steganography LSB (with PRNG by seed)",
    "version": "0.2",
    "project_urls": {
        "Homepage": "https://github.com/NonProjects/steganon"
    },
    "split_keywords": [
        "steganography",
        "lsb",
        "cryptography"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "2825a69e37cfcaad246bfc8817c3c700291d7d53c8f955f93154b93d1ded1818",
                "md5": "3a07eab8fc75802cacb0888326c07bea",
                "sha256": "7b67ed4b3ba9863f3ecec9a2ee3cb2249688700ca85640abcb059c29c62b3489"
            },
            "downloads": -1,
            "filename": "steganon-0.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "3a07eab8fc75802cacb0888326c07bea",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 20212,
            "upload_time": "2024-02-01T17:22:10",
            "upload_time_iso_8601": "2024-02-01T17:22:10.038877Z",
            "url": "https://files.pythonhosted.org/packages/28/25/a69e37cfcaad246bfc8817c3c700291d7d53c8f955f93154b93d1ded1818/steganon-0.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "e959aa0926f34a268a74fa9e23b78e3d931dc5dc1e40e09b20993f30dbb75f28",
                "md5": "3ad07d3570448b74a196deb7d2ac14d5",
                "sha256": "927f1b98f12a5334bba44ddb5072d08771695907840916faa01d83d9fd1ec1db"
            },
            "downloads": -1,
            "filename": "steganon-0.2.tar.gz",
            "has_sig": false,
            "md5_digest": "3ad07d3570448b74a196deb7d2ac14d5",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 21395,
            "upload_time": "2024-02-01T17:22:18",
            "upload_time_iso_8601": "2024-02-01T17:22:18.823710Z",
            "url": "https://files.pythonhosted.org/packages/e9/59/aa0926f34a268a74fa9e23b78e3d931dc5dc1e40e09b20993f30dbb75f28/steganon-0.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-02-01 17:22:18",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "NonProjects",
    "github_project": "steganon",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "steganon"
}
        
Elapsed time: 0.18683s