User Tools

Site Tools


user:sachy:svgsteg

Vektorova steganografie

Na skryte zapisovani dat do bitmap existuje spousta nastroju, ale jeste vic clanku, bakalarek a diplomek na jejich detekci a ziskani. To same plati pro video a zvuk - proste se jemne deformace ztrati v sumu.

Naproti tomu vektory nabizi moznost zapisu informace bez kvalitativni zmeny vystupu.

Zakladni metody jsou:

  • Jittering - zmeny nejnizsich bitu barev/pozic/delek nebo pridavani nevyznamnych nul na zacatek integeru/konec floatu
  • Segmentace - rozdeleni usecek na mensi casti (pouzivaji se dva body - pivot (je dana usecka zakodovana?) a bod (ktery bud existuje=1, nebo ne=0) v pevne danych pomerech delek). Hlavni nevyhodou je ztrata informace pri pruchodu optimalizatorem (ktery nadbytecne body na rovne usecce vyhodi).
  • Polygonizace - prevedeni (Bezierovych) krivek na polygon, hlavni vyhodou je moznost ulozit velke mnozstvi informace do jednoho segmentu, a polygonizace vypada nenapadne (vykonnostni duvody).
  • Pridani novych objektu ktere splynou s pozadim/jsou prekryty jinym objektem. Nevyhodou je slozitejsi zpracovani (generator musi umet zpracovat vysledny obraz, nestaci parsovat XML.

Proof-of-koncept svgsteg.sh

#!/bin/bash
#
# Read SVG file "$1" and write msg "$2" to file "$3"
#

cp -f "$1" "$3"

bits=$(cat "$3" | grep -o -e '[0-9]\+\.[0-9]\{2,\}' | wc -l)
msgb=$(echo "$2" | perl -pe 'local $/; $_=unpack"B*"')
msgl=$(echo "$msgb" | tr -d '\n' | wc -c)
msgbl=$(echo $msgl | awk '{print "ibase=10;obase=2;" $msgl}' | bc | xargs printf "%064d\n")
msgfull="$msgbl$msgb"

if [ $(($msgl + 64)) -gt "$bits" ]
then
	echo "Msg too big or SVG too simple";
	exit;
fi

nums=$(cat "$3" | grep -o -e '[0-9]\+\.[0-9]\{2,\}')

i="1"
echo "$msgfull" | tr -d '\n' | while IFS= read -r -n1 bit; do

	num=$(echo "$nums" | head -n "$i" | tail -n 1)

	ldigit=$(echo "$num" | grep -o -e '[0-9]$')
	odd=$(( $ldigit & 1))

	# if already even or already odd; do nothing
	# if even shall be odd; add one to least place (ignore overflow)
	# if odd shall be even; add one to least place (ignore overflow)

	if [[ $bit != $odd ]]
	then
		# add 1 to $ldigit, but store only last digit (in case 9->10 = 0)
		newldigit=$(echo $(($ldigit + 1)) | grep -o -e '[0-9]$')
		# get updated number
		upnum=$(echo "$num" | sed -e "s/[0-9]$/$newldigit/g" -r)

		# update the file
		sed -n "1h;2,\$H;\${g;s/[0-9]\+\.[0-9]\{2,\}/$upnum/$i;p}" -i "$3"

	fi

	i=$(($i + 1))
done

A dekoder svgunsteg.sh

#!/bin/bash
#
# Get message from SVG file $1
#

msg=""

nums=$(cat "$1" | grep -o -e '[0-9]\+\.[0-9]\{2,\}')

i="1"
echo "$nums" | while IFS= read num; do
	ldigit=$(echo $num | grep -o -e '[0-9]$')
	odd=$(($ldigit & 1))

	msg="$msg$odd"

	if [[ $i = "64" ]]
	then
		mlen="$((2#$msg))"
		msg=""
	fi

	if [[ $i = "$(($mlen+64))" ]]
	then
		echo "$msg" | perl -lpe '$_=pack"B*",$_'
		exit
	fi

	i=$(($i + 1))
done

Obrazek se skrytou informaci

user/sachy/svgsteg.txt · Last modified: 2017/08/03 20:28 by sachy