Member 14153431 Ответов: 1

Как бы я маскировался в этом коде?


I discovered that in java does not support 32 but integers. I had errors that i was getting when I had it in that form. So I switched over to BigInteger think it would fix this problem. So I kept on using BigInteger through the left and right shifting. Now i'm facing the problem of not getting the right output.
Я использую BigInteger для хранения 128-байтового ключа. Но когда я запускаю свой код, он дает мне неправильный вывод. И то, что я читал, было то, что можно использовать маскировку, которая решила бы эту проблему.

Что я уже пробовал:

when inputting the plaintText as: "0x0123456789ABCDEF"

Output is:

    Original Plain Text:0x0123456789ABCDEF
    CipherText:0xa0761126d09724fd
    Decrypted CipherText is:0x8d5a4a234b3c6720

But when i input: 0x123456789ABCDEF

The output is:

    Invalid block size!
    Original Plain Text:0x123456789ABCDEF
    CipherText:null


What am I doing wrong?

Here's my code: 

   
import java.math.BigInteger;
    
    public class TEA {
    
        BigInteger [] K ; //128 bits key
        private String plainText;
        public static final BigInteger delta = new BigInteger("9e3779b9",16);
    
    
        //constructor receives a string of plaintext and 128 bit key in hexadecimal
        public TEA(String plainText, String key)
        {
            parseKey(key);
    
    
        }
    
        //constructor receives a hexadecimal 
        public TEA(String key)
        {
    
            parseKey(key);
    
        }
    
        //parses a 128 bit key, given in hexadecimal form, and store its value in 4 integers (total of 128 bits), 
        private void parseKey(String key)
        {
            if(key.substring(0,2).equals("0x"))
                key= key.substring(2);
    
            //validating input
            if(key.length() != 32)
            {
                System.out.println("Invalid key size!");
                return;
            }
    
    
            //dividing the key into 4 strings
            String[] kStr = new String[4];
            int index=-1;
            for(int i=0; i<key.length(); i++)
            {
                if(i%8 == 0)
                {
                    index++;
                    kStr[index]="";
    
                }
                kStr[index] = kStr[index] + key.charAt(i);
            }
    
    
            //converting the 4 hex strings into 4 integers
            K= new BigInteger[4];
            for(int i=0; i<4; i++)
                K[i] = new BigInteger(kStr[i], 16); 
    
        }
    
        //receives a plaintext block of 64 bits in hexadecimal to be encrypted
        //returns the cipher block
        String encryptBlock(String plainTextBlock)
        {
            if(plainTextBlock.substring(0,2).equals("0x"))
                plainTextBlock= plainTextBlock.substring(2);
    
            //validating input
            if(plainTextBlock.length()!=16)
            {
                System.out.println("Invalid block size!");
                return null;
    
            }
    
            //separating the string block into left and right blocks
            String LStr = plainTextBlock.substring(0, 8); //left block (32 bit)
            String RStr = plainTextBlock.substring(8); //right block (32 bit)
    
            //converting left and right blocks to integers
            BigInteger L = new BigInteger(LStr, 16);
            BigInteger R = new BigInteger(RStr, 16);
    
    
            BigInteger sum= new BigInteger("0");
            //32 rounds
            for(int i=0; i<32; i++)
            {
                sum = sum.add(delta);
                L= sum(L,  (sum(shiftLeft(R,4),K[0]))   .xor(sum(R,sum))    .xor(sum(shiftRight(R,5),K[1]))) ;
                R= sum(R,  (sum(shiftLeft(L,4),K[2]))   .xor(sum(L,sum))    .xor(sum(shiftRight(L,5),K[3]))) ;
    
                //R= R.add(  (shiftLeft(R,4).add(K[2])).xor(L.add(sum)).xor(shiftRight(L,5).add(K[3])) );
    
    
            }
    
            //joining back the blocks as hex
            String cipherBlock = "0x"+L.toString(16)+R.toString(16)+"";
    
    
            return cipherBlock;
        }
    
    
        //receives a ciphertext block of 64 bits in hexadecimal to be decrypted
        //returns the plaintext block
        String decryptBlock(String cipherBlock)
        {
            if(cipherBlock.substring(0,2).equals("0x"))
                cipherBlock= cipherBlock.substring(2);
    
            //validating input
            if(cipherBlock.length()!=16)
            {
                System.out.println("Invalid block size!");
                return null;
    
            }
    
            //separating the string block into left and right blocks
            String LStr = cipherBlock.substring(0, 8); //left block (32 bit)
            String RStr = cipherBlock.substring(8); //right block (32 bit)
    
            //converting left and right blocks to integers
            BigInteger L = new BigInteger(LStr, 16);
            BigInteger R = new BigInteger(RStr, 16);
    
            BigInteger sum= shiftLeft(delta,5);
            //32 rounds
            for(int i=0; i<32; i++)
            {
    
                R= subtract(R,  (sum(shiftLeft(L,4),K[2]))   .xor(sum(L,sum))    .xor(sum(shiftRight(L,5),K[3]))) ;
                L= subtract(L,  (sum(shiftLeft(R,4),K[0]))   .xor(sum(R,sum))    .xor(sum(shiftRight(R,5),K[1]))) ;
    
    
                //R= R.subtract(  (L.shiftLeft(4).add(K[2])).xor(L.add(sum)).xor(L.shiftRight(5).add(K[3])) );
                //L= L.subtract(  (R.shiftLeft(4).add(K[0])).xor(R.add(sum)).xor(R.shiftRight(5).add(K[1])) );
                sum = sum.subtract(delta);  
            }
    
            //joining back the blocks as hex
            String plainTextBlock = "0x"+L.toString(16)+R.toString(16)+"";
    
    
            return plainTextBlock;
        }
    
    
        private BigInteger shiftLeft(BigInteger x, int steps)
        {
    
           BigInteger shifted=null;
           boolean negative =false;
    
           String xStr = x.toString(2);
    
           //removing negative sign while shifting (currently)
           if(xStr.charAt(0)=='-')
           {
               negative= true;
               xStr = xStr.substring(1);
           }
    
    
           int additionalSize = 32- xStr.length();
    
           for(int i=0; i<additionalSize; i++)
               xStr= "0"+xStr;
    
    
    
           for(int i=0; i<steps; i++)
           {
               xStr = xStr.substring(1);
               xStr = xStr+"0";
           }
    
           //one last addition of negative sign if the number is negative
           if(negative==true)
               xStr= "-"+xStr;
    
           //System.out.println(xStr);
          shifted = new BigInteger(xStr,2);
    
            return shifted;
        }
    
    
        private BigInteger shiftRight(BigInteger x, int steps)
        {
           BigInteger shifted=null;
           boolean negative = false;
    
           String xStr = x.toString(2);
    
           //removing negative sign while shifting (currently)
           if(xStr.charAt(0)=='-')
           {
               negative= true;
               xStr = xStr.substring(1);
           }
    
           int additionalSize = 32- xStr.length();
    
           for(int i=0; i<additionalSize; i++)
               xStr= "0"+xStr;
    
    
           for(int i=0; i<steps; i++)
           {
               xStr = xStr.substring(0,xStr.length()-1);
               xStr = "0"+xStr;
           }
    
           //one last addition of negative sign if the number is negative
           if(negative==true)
               xStr= "-"+xStr;
    
          shifted = new BigInteger(xStr,2);
    
            return shifted;
        }
    
        private BigInteger sum(BigInteger a, BigInteger b)
        {
    
            BigInteger sum = a.add(b);
            String sumStr = sum.toString(2);
            if(sumStr.length()>32)
            {
                int diff = sumStr.length()- 32;
                sumStr = sumStr.substring(diff);
            }
    
            BigInteger newSum = new BigInteger(sumStr,2);
    
            return newSum;
        }
    
        private BigInteger subtract(BigInteger a, BigInteger b)
        {
    
            BigInteger sub = a.subtract(b);
    
            String subStr = sub.toString(2);
            if(subStr.length()>32)
            {
                int diff = subStr.length()- 32;
                subStr = subStr.substring(diff);
            }
    
            BigInteger newSub = new BigInteger(subStr,2);
    
            return newSub;
        }
    
    
    
        public static void main(String[] args)
        {
    
            String plainText="0x0123456789ABCDEF";
            String key= "0xA56BABCD00000000FFFFFFFFABCDEF01";
            TEA tea = new TEA(key);
            String cipherText = tea.encryptBlock(plainText);
            System.out.println("Original Plain Text:"+plainText);
            System.out.println("CipherText:"+cipherText);
            System.out.println("Decrypted CipherText is:"+tea.decryptBlock(cipherText));
    
    
    
    
        }
    
    
    }

Richard Deeming

Почему вы думаете, что Java не поддерживает 32-битные целые числа?

Примитивные типы данных (учебные пособия Java™ > изучение языка Java > основы языка)[^]
"int: по умолчанию тип данных int представляет собой 32-битное целое число дополнения со знаком два, которое имеет минимальное значение -231 и максимальное значение 231-1. в Java SE 8 и более поздних версиях тип данных int можно использовать для представления 32-разрядного целого числа без знака, которое имеет минимальное значение 0 и максимальное значение 232-1. Использовать integer класс использовать int тип данных целое число без знака."

Chad3F

Примечание: используйте key.startsWith("0x") вместо создания подстроки и сравнения ее с "0x".

1 Ответов

Рейтинг:
0

Maciej Los

Я не знаю, что не так с вашим кодом, но похоже, что вы хотите заставить двери широко открыться...

Ява поддержка процессоров шифрования/дешифрования через СКА[^]. Итак, я хотел бы предложить, чтобы использовать классы СКА...
Например: Java Secure Hashing - MD5, SHA256, SHA512, PBKDF2, BCrypt, SCrypt[^]