Reputation: 25
my AES algorithm work nice for a text but when I tried to adapt it to image it still not working. all seems to be logical to me and cannot find where is the troubles. thanks this is the main program , I split the matrix into 4x4 sub matrix then i use aesencrypt/aesdecrypt function (this too functions work good for a text)
function [encrypt] = aes(s, oper, mode, I, iv, sbit)switch lower(oper)
case {'encrypt', 'enc', 'e'}
oper = 0;
case {'decrypt', 'dec', 'd'}
oper = 1;
otherwise
error('Bad ''oper'' parameter.');
end
E.sub_mat=[];
E.final=[];
[m n]=size(I);
p=m/4*n/4;
k=1;
%Splite the image matrix into 4*4 sub matrix
for j=1:4:m
for i=1:4:n
E.sub_mat{k}=imcrop(I,[i,j,3,3]);
k=k+1;
end
end
input =zeros(4,4,'double');
blocks=p;
l=1;
for l=1:blocks
input = E.sub_mat{l};
switch lower(mode)
case {'ecb'}
% Electronic Codebook Mode
% ------------------------
output = zeros(4,4,'double');
if (oper)
% decrypt
output = aesdecrypt(s,input);
else
% encrypt
output = aesencrypt(s,input);
end
% Dites ceci est la matrice donnée:
case {'cbc'}
% Cipher Block Chaining Mode
% --------------------------
if (nargin < 5)
error('Missing initialization vector ''iv''.');
end
output = zeros(4,4,'double');
ob = iv;
if (oper)
% decrypt
in = input;
output = bitxor(ob(:), aesdecrypt(s,in)');
ob = in;
else
% encrypt
ob = bitxor(ob(:), input(idx));
ob = aesencrypt(s, ob);
output = ob;
end
% store iv for block passing
s.iv = ob;
case {'cfb'}
% Cipher Feedback Mode
% --------------------
% Special mode with bit manipulations
% sbit = 1..128
if (nargin < 6)
error('Missing ''sbit'' parameter.');
end
% get number of bits
input=input(:);
bitlen = 8*length(input);
% loop counter
rounds = round(bitlen/sbit);
% check
if (rem(bitlen, sbit))
error('Message length in bits is not multiple of ''sbit''.');
end
% convert input to bitstream
inputb = reshape(de2bi(input,8,2,'left-msb')',1,bitlen);
% preset init. vector
ib = iv;
ibb = reshape(de2bi(ib,8,2,'left-msb')',1,128);
% preset output binary stream
outputb = zeros(size(inputb));
for i = 1:rounds
iba = aesencrypt(s, ib);
% convert to bit, MSB first
ibab = reshape(de2bi(iba,8,2,'left-msb')',1,128);
% strip only sbit MSB bits
% this goes to xor
ibab = ibab(1:sbit);
% strip bits from input
inpb = inputb((i - 1)*sbit + (1:sbit));
% make xor
outb = bitxor(ibab, inpb);
% write to output
outputb((i - 1)*sbit + (1:sbit)) = outb;
if (oper)
% decrypt
% prepare new iv - bit shift
ibb = [ibb((1 + sbit):end) inpb];
else
% encrypt
% prepare new iv - bit shift
ibb = [ibb((1 + sbit):end) outb];
end
% back to byte ary
ib = bi2de(vec2mat(ibb,8),'left-msb');
% loop
end
output = bi2de(vec2mat(outputb,8),'left-msb');
% store iv for block passing
s.iv = ib;
output=reshape(output,4,4);
case {'ofb'}
% Output Feedback Mode
% --------------------
if (nargin < 5)
error('Missing initialization vector ''iv''.');
end
output = zeros(4,4,'double');
ib = iv;
% encrypt, decrypt
ib = aesencrypt(s, ib);
output = bitxor(ib(:), input);
% store iv for block passing
s.iv = ib;
case {'ctr'}
% Counter Mode
% ------------
if (nargin < 5)
iv = 1;
end
input=input(:);
output = zeros(1,length(input));
idx = 1:16;
for i = (iv):(iv + blocks - 1)
ib = AES_GET_COUNTER(i);
ib = aesencrypt(s, ib);
output(idx) = bitxor(ib(:), input(idx));
idx = idx + 16;
end
s.iv = iv + blocks;
output=reshape(output,4,4);
otherwise
error('Bad ''oper'' parameter.');
end
E.final{l}=output;
end
encrypt=zeros(m,n,'double');
a=1;
for i=1:(m/4)
for j=1:(n/4)
r2=4*i;r1=r2-3;
c2=4*j;c1=c2-3;
encrypt(r1:r2,c1:c2)=E.final{a};
a=a+1;
end
end
aesencrypt function
function [out] = aesencrypt(s, in) state = in;
% Initial round
% AddRoundKey keyexp(1:4)
state = bitxor(state, (s.keyexp(1:4, :))');
% Loop over (s.rounds - 1) rounds
for i = 1:(s.rounds - 1)
% SubBytes - lookup table
state = s.s_box(state + 1);
% ShiftRows
state = shift_rows(state, 0);
% MixColumns
state = mix_columns(state, s);
% AddRoundKey keyexp(i*4 + (1:4))
state = bitxor(state, (s.keyexp((1:4) + 4*i, :))');
end
% Final round
% SubBytes - lookup table
state = s.s_box(state + 1);
% ShiftRows
state = shift_rows(state, 0);
% AddRoundKey keyexp(4*s.rounds + (1:4))
state = bitxor(state, (s.keyexp(4*s.rounds + (1:4), :))');
out = state;
aesdecrypt function
function [out] = aesdecrypt(s, in)state = in;
% Initial round
% AddRoundKey keyexp(s.rounds*4 + (1:4))
state = bitxor(state, (s.keyexp(s.rounds*4 + (1:4), :))');
% Loop over (s.rounds - 1) rounds
for i = (s.rounds - 1):-1:1
% ShiftRows
state = shift_rows(state, 1);
% SubBytes - lookup table
state = s.inv_s_box(state + 1);
% AddRoundKey keyexp(i*4 + (1:4))
state = bitxor(state, (s.keyexp((1:4) + 4*i, :))');
% MixColumns
state = mix_columns(state, s);
end
% Final round
% ShiftRows
state = shift_rows(state, 1);
% SubBytes - lookup table
state = s.inv_s_box(state + 1);
% AddRoundKey keyexp(1:4)
state = bitxor(state, (s.keyexp(1:4, :))');
out = state;
TEST FILE
[file path]=uigetfile('*.*','Select the Input Image');
Img=imread([path file]);
keyh= {'2b' '7e' '15' '16' '28' 'ae' 'd2' 'a6'...
'ab' 'f7' '15' '88' '09' 'cf' '4f' '3c'};
key = hex2dec(keyh);
s = aesinit(key);
[n m h]=size(Img);
R=Img(:,:,1);
G = Img(:,:,2);
B = Img(:,:,3);
R=double(R);
G=double(G);
B=double(B);
x=length(R);
ivh = {'00' '01' '02' '03' '04' '05' '06' '07'...
'08' '09' '0a' '0b' '0c' '0d' '0e' '0f'};
iv = hex2dec(ivh);
s = aesinit(key);
mode= input('entrer le choix:')
switch lower(mode)
case {'decrypt', 'dec', 'd'}
mode = input('entrer le mode:')
switch lower(mode)
case {'ecb'}
image_decrypt_R = aes(s, 'dec', 'ecb', R);
image_decrypt_G = aes(s, 'dec', 'ecb', G);
image_decrypt_B = aes(s, 'dec', 'ecb', B);
case {'cbc'}
image_decrypt_R = aes(s, 'dec', 'cbc', R, iv);
image_decrypt_G = aes(s, 'dec', 'cbc', G , iv);
image_decrypt_B = aes(s, 'dec', 'cbc', B , iv);
case {'cfb'}
sbit= input('entrer 0<sbit<128 ')
image_decrypt_R = aes(s, 'dec', 'cfb', R, iv, sbit);
image_decrypt_G = aes(s, 'dec', 'cfb', G, iv, sbit);
image_decrypt_B = aes(s, 'dec', 'cfb', B, iv, sbit);
case {'ofb'}
image_decrypt_R = aes(s, 'dec', 'ofb', R , iv);
image_decrypt_G = aes(s, 'dec', 'ofb', G , iv);
image_decrypt_B = aes(s, 'dec', 'ofb', B , iv);
otherwise
error( 'bad''oper''parameter.');
end
image_decrypt = cat(3,image_decrypt_R, image_decrypt_G, image_decrypt_B);
Image = image_decrypt;
imwrite(Image, 'image_decryptée.jpg');
case {'encrypt', 'enc', 'e'}
mode = input('entrer le mode:')
switch lower(mode)
case {'ecb'}
image_crypt_R = aes(s, 'enc', 'ecb', R);
image_crypt_G = aes(s, 'enc', 'ecb', G);
image_crypt_B = aes(s, 'enc', 'ecb', B);
case {'cbc'}
image_crypt_R = aes(s, 'enc', 'cbc', R, iv);
image_crypt_G = aes(s, 'enc', 'cbc', G , iv);
image_crypt_B = aes(s, 'enc', 'cbc', B , iv);
case {'cfb'}
sbit= input('entrer 0<sbit<128 ')
image_crypt_R = aes(s, 'enc', 'cfb', R, iv, sbit);
image_crypt_G = aes(s, 'enc', 'cfb', G, iv, sbit);
image_crypt_B = aes(s, 'enc', 'cfb', B, iv, sbit);
case {'ofb'}
image_crypt_R = aes(s, 'enc', 'ofb', R , iv);
image_crypt_G = aes(s, 'enc', 'ofb', G , iv);
image_crypt_B = aes(s, 'enc', 'ofb', B , iv);
otherwise
error( 'bad''oper''parameter.');
end
image_crypt = cat(3,image_crypt_R, image_crypt_G, image_crypt_B);
Image = image_crypt;
imwrite(Image, 'image_cryptée.jpg');
otherwise
error('Bad ''oper'' parameter.');
end
Upvotes: 0
Views: 507
Reputation: 19981
You're writing your encrypted image to a JPEG file. JPEG is a lossy compressed format, and the resulting file will not have the exact same pixel values as were in the image.
The differences are typically small and unobtrusive to the human eye. But it is in the nature of encryption that a tiny difference in ciphertext may mean a complete scrambling of the plaintext.
So, you take your image; you encrypt its pixel values using AES (OK so far); you write it out to a JPEG image; you read it back in -- and now the pixel values have changed. You decrypt its pixel values using AES, and you get nonsense -- because the ciphertext you are decrypting is not the result of an AES encryption, it's the result of an AES encryption plus the errors introduced by JPEG compression.
Upvotes: 2