Joe.Ou
Joe.Ou

Reputation: 25

Image decrypted look like the encrypted one using AES

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

Answers (1)

Gareth McCaughan
Gareth McCaughan

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

Related Questions