LSB стеганографиясы

Бір кездері мен өзімді жаздым хабтағы бірінші жазба. Және бұл пост өте қызықты мәселеге, атап айтқанда стеганографияға арналды. Әрине, сол ескі тақырыпта ұсынылған шешімді сөздің шын мағынасында стеганография деп атауға болмайды. Бұл жай ғана файл пішімдері бар ойын, бірақ соған қарамастан өте қызықты ойын.

Бүгін біз аздап тереңірек қазып, LSB алгоритмін қарастыруға тырысамыз. Егер сізді қызықтырса, мысықтың астына қош келдіңіз. (Кісінің астында трафик: шамамен мегабайт.)

Ең алдымен, қысқаша кіріспе жасау керек. Криптографияның мақсаты құпия ақпаратты оқуды мүмкін етпеу екенін бәрі біледі. Әрине, криптографияның өз қосымшалары бар, бірақ деректерді қорғаудың басқа тәсілі бар. Біз ақпаратты шифрлаудың қажеті жоқ, бірақ ол бізде жоқ деп елестету. Стеганография дәл осы себепті ойлап табылды. Википедия бізді «стеганография (грек тілінен στεγανοσ - жасырын және грек γραφω - жазамын, сөзбе-сөз «құпия жазу») - бұл жіберу фактісін құпия сақтай отырып, ақпаратты жасырын беру туралы ғылым деп сендіреді.

Әрине, криптографиялық және стеганографиялық әдістерді біріктіруге ешкім тыйым салмайды. Оның үстіне, іс жүзінде олар мұны істейді, бірақ біздің міндетіміз - негіздерді түсіну. Егер сіз Википедия мақаласын мұқият зерттесеңіз, стеганография алгоритмдері деп аталатындарды қамтитынын білесіз. контейнер және хабарлама. Контейнер - бұл құпия хабарламаны жасыруға көмектесетін кез келген ақпарат.

Біздің жағдайда контейнер BMP пішіміндегі сурет болады. Алдымен осы файлдың құрылымын қарастырайық. Файлды 4 бөлікке бөлуге болады: файл тақырыбы, сурет тақырыбы, палитра және суреттің өзі. Біздің мақсаттарымыз үшін біз тек тақырыпта не жазылғанын білуіміз керек.

Тақырыптың алғашқы екі байты BM қолтаңбасы болып табылады, содан кейін байттағы файл өлшемі қос сөзбен жазылады, келесі 4 байт сақталады және нөлдерден тұруы керек, және соңында, басқа қос сөзде басынан ығысу болады. файлды кескіннің нақты байттарына дейін жеткізіңіз. 24 биттік bmp файлында әрбір пиксел үш BGR байтпен кодталған.

Енді біз кескінге қалай жетуге болатынын білеміз, тек сол жерде бізге қажетті ақпаратты қалай жазуға болатынын түсіну ғана қалады. Ол үшін бізге LSB әдісі қажет болады. Әдістің мәні келесідей: біз түсті кодтауға жауапты байттардағы ең аз маңызды биттерді ауыстырамыз. Айталық, егер құпия хабарламамыздың келесі байты 11001011 болса, ал суреттегі байттар...11101100 01001110 01111100 0101100111... болса, кодтау келесідей болады. Біз құпия хабарлама байты екі разрядты 4 бөлікке бөлеміз: 11, 00, 10, 11 және кескіннің төменгі ретті биттерін алынған фрагменттермен ауыстырамыз: ...11101111 01001100 01111110 0101100111…. Мұндай ауыстыру әдетте адам көзіне байқалмайды. Сонымен қатар, көптеген ескі шығыс құрылғылары мұндай шағын өзгерістерді көрсете алмайды.

Маңыздылығы аз 2 битті ғана емес, олардың кез келген санын өзгертуге болатыны анық. Келесі үлгі бар: біз неғұрлым көп бит өзгертсек, соғұрлым көп ақпаратты жасыра аламыз және бұл бастапқы кескінге соғұрлым көп кедергі тудырады. Мысалы, мұнда екі сурет бар:

LSB стеганографиясы
LSB стеганографиясы

Бар күш-жігерімді жұмсағаныма қарамастан, мен олардың арасындағы айырмашылықты көре алмадым, бірақ соған қарамастан, екінші суретте сипатталған әдісті қолдана отырып, Льюис Кэрроллдың «Снаркты аулау» поэмасы жасырылған. Егер сіз осы уақытқа дейін оқыған болсаңыз, онда сіз іске асыру туралы білуге ​​мүдделі болуыңыз мүмкін. Бұл өте қарапайым, бірақ мен сізге бәрі Delphi-де жасалғанын бірден ескертемін. Мұның екі себебі бар: 1. Менің ойымша, Delphi жақсы тіл; 2. Бұл бағдарлама компьютерлік көру негіздері курсын дайындау барысында дүниеге келген және мен бұл курсты оқытып жатқан жігіттер әлі Delphi-ден басқа ештеңе білмейді. Синтаксиспен таныс емес адамдар үшін бір нәрсені түсіндіру керек: shl x - солға биттік ығысу х, shr x - бит бойынша оңға х жылжыту.

Жолда сақталған мәтінді контейнерге жазып, төменгі екі байтты ауыстырамыз деп есептейміз:
Жазу коды:

for i:=1 to length(str) до
    бастаңыз
      l1:=байт(str[i]) shr 6;
      l2:=byte(str[i]) shl 2; l2:=l2 shr 6;
      l3:=byte(str[i]) shl 4; l3:=l3 shr 6;
      l4:=byte(str[i]) shl 6; l4:=l4 shr 6;
 
      f.ReadBuffer(tmp,1);
      f.Position:=f.Position-1;
      tmp:=((tmp shr 2) shl 2)+l1;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Position:=f.Position-1;
      tmp:=((tmp shr 2) shl 2)+l2;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Position:=f.Position-1;
      tmp:=((tmp shr 2) shl 2)+l3;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Position:=f.Position-1;
      tmp:=((tmp shr 2) shl 2)+l4;
      f.WriteBuffer(tmp,1);
 
    аяғында;

оқу үшін код:

i:=1 үшін MsgSize орындаңыз
    бастаңыз
      f.ReadBuffer(tmp,1);
      l1:=tmp shl 6;
      f.ReadBuffer(tmp,1);
      l2:=tmp shl 6; l2:=l2 shr 2;
      f.ReadBuffer(tmp,1);
      l3:=tmp shl 6; l3:=l3 shr 4;
      f.ReadBuffer(tmp,1);
      l4:=tmp shl 6; l4:=l4 shr 6;
      str:=str+char(l1+l2+l3+l4);
    аяғында;

Ал, шынымен жалқаулар үшін - бағдарламаға және оның бастапқы кодына сілтеме.

рахмет.

Ақпарат көзі: www.habr.com

пікір қалдыру