蛮力攻击AES 192b

时间:2019-11-09 11:27:31

标签: java cryptography aes

我有一个任务,必须在CBC模式下强制使用AES-192加密的.enc文件。

因此,我要做的第一件事是尝试使用Java和Crypto库进行脱机字典攻击,问题在于字典中的平均单词长8位,因此密码必须以某种方式添加盐分。 问题是我编写的程序在每次执行时都会输出不同的密码,而输出只是无法读取的文本。

这是主要内容:

public class main {

    public static void main(String[] args) {
        bruteForceFile();
    }   

    /*
     * Tries to brute force the file reading all the possible keys from a dictionary
     * */
    private static void bruteForceFile() {

        System.out.println("--------------------------------------------------------");
        System.out.println("Starting brute force/dictionary attack:");
        try {
            byte[] file = cipherText.cipherText.getInstance().getFileArray();
            bruteForceWrapper enc = new AES(OperatingMode.CBC).bruteForceFile(file);
            System.out.println("decription succeded, key : " + enc.key + " elapsed time: " + enc.elapsedSeconds +"s");
            System.out.println("--------------------------------------------------------");
            System.out.println("Decripted message:\n");
            System.out.println(new String(enc.data));


        }catch(Exception e) {
            e.printStackTrace();
        }
    }
}

这是AES类:

/**
 *Advanced Encryption Standard as specified by NIST in FIPS 197. Also known as the Rijndael 
 *algorithm by Joan Daemen and Vincent Rijmen, 
 *AES is a 128-bit block cipher supporting keys of 128, 192, and 256 bits.
 */
public class AES extends cipher.AbstractCipher {


    public AES(OperatingMode opm) {
        super(opm);
        super.enablePadding();
    }


    @Override
    protected String getMode() {
        if(opm == OperatingMode.CBC) {
            if(padding) 
                return "AES/CBC/PKCS5Padding";

            return "AES/CBC/NoPadding";
        }

        else {
            if(padding) 
                return "AES/ECB/PKCS5Padding";

            return "AES/ECB/NoPadding";
        }
    }



    @Override
    public encriptionWrapper encript(byte[] plainText,AbstractCipherKey key) {
        return null;
    }

    @Override
    public encriptionWrapper decript(byte[]cipherText,AbstractCipherKey key) {

        StopWatch timer = new StopWatch();

        if(super.print) {
            System.out.println("------------------------------------------------------------");
            System.out.println("Starting " + this.toString() + " decryption" + " in " 
                    + opm.toString() + " mode."+ " (" + this.getMode() + ")");

        }
        try {


            Cipher dcipher = Cipher.getInstance("AES");
            AESCipherKey aes_key = (AESCipherKey)key;
            byte[] b_key = aes_key.getPassword().getBytes("UTF-8");

            MessageDigest sha = MessageDigest.getInstance("SHA-1");
            b_key = sha.digest(b_key);
            b_key = Arrays.copyOf(b_key, 16); 

            SecretKeySpec secretKeySpec = new SecretKeySpec(b_key, "AES");

            dcipher.init(Cipher.DECRYPT_MODE, secretKeySpec);// decode with base64 to get bytes


            byte[] utf8 = dcipher.doFinal(cipherText);
            // create new string based on the specified charset

            if(super.print) {

                System.out.println("Encryption ended. Elapsed Time: " + timer.getSeconds() + "s");
                System.out.println("encrypted message length: " + utf8.length);
                System.out.println("------------------------------------------------------------");

            }

            return new encriptionWrapper(utf8,timer.getSeconds());


        } catch (Exception e) {

            /*if(e.getClass() == BadPaddingException.class) {
                System.out.println("attempt failed....");
            }*/

            if(super.print) {
                System.out.println(this.toString() + " decryption failed. \n");
                System.out.println("decryption ended. Elapsed Time: " + timer.getSeconds() + "s");
                System.out.println("------------------------------------------------------------\n");
            }

            return null;
        }
    }

    /*
     * Try to brute force an encrypted file with AES
     */
    public bruteForceWrapper bruteForceFile(byte[] encrypted) {

        StopWatch watch = new StopWatch();
        Dictionary dic = new Dictionary();
        bruteForceWrapper wrapper;
        super.print = false;

        System.out.print("Decrypting...");
        while(1 == 1) {
            if(dic.getProvidedWords().size()%10 == 0) {
                System.out.print(".");
            }
            encriptionWrapper enc = decript(encrypted,new AESCipherKey(dic.getWord()));
            if(enc != null) {
                wrapper = new bruteForceWrapper(enc.data, watch.getSeconds());
                break;
            }

        }
        super.print = true;
        wrapper.tried_keys = dic.getProvidedWords();

        wrapper.key = dic.getProvidedWords().get(dic.getProvidedWords().size() - 1);
        return wrapper;

    }

    @Override
    public String toString() {
        return "AES";
    }

}

最后是AESCipherKey类:

public class AESCipherKey extends AbstractCipherKey{


    private String SHA_TEC = "SHA-1";


    public AESCipherKey(String key) {
        super(key);
    }

    /**
     *Return the desription of the safeness of the key(unsafe is user generated)
     */
    @Override
    public String getKeySafenessDescription() {
        if(isKeySafe) {
            return "(safe key)";
        }else
            return "(unsafe key)";
    }



    @Override
    public boolean validate() {

        if(super.isKeySafe)
            return true;

        if(super.getByteArray().length != 16) {
            System.out.println("Invalid AES key: " + super.key);
            return false;
        }
        return true;
    }

    @Override
    public void generateSecureKey() {
        KeyGenerator keyGen;
        try {
            keyGen = KeyGenerator.getInstance("AES");
            keyGen.init(256);
            super.safeKey = keyGen.generateKey();
            super.isKeySafe = true;
        } catch (NoSuchAlgorithmException e) {
            System.out.println("Error generating AES safe key");
            e.printStackTrace();
        }
    }

    public String getPassword() {
        return super.key;
    }

}

所以我认为问题就在这里:

 byte[] b_key = aes_key.getPassword().getBytes("UTF-8");

                MessageDigest sha = MessageDigest.getInstance("SHA-1");
                b_key = sha.digest(b_key);
                b_key = Arrays.copyOf(b_key, 16); 

                SecretKeySpec secretKeySpec = new SecretKeySpec(b_key, "AES");

但是我找不到错误,这里是解密的一些输出:

--------------------------------------------------------
Starting brute force/dictionary attack:
Decrypting................decription succeded, key : enantiopathia elapsed time: 12.995s
--------------------------------------------------------
Decripted message:

"��t����O����m�V��}s1��i#a7� B<2�B֯�R�E�\!��v���k��WK�m��'hՒ���g�y�$�s�ug���
X��l=qYX�����F%�y)���>��r܅͞��i��L'FG��c6-�}���-�|�L�#�n���Ӧ���)�\�o�2|?7/ə���Lc�����-
�/���*���"sK���*[U�ɮ�����s��ec�P��z�6v�����Ov��1e����w�5����t�{s�%���|��W���'�3�^�H�Td��k1���S���l�8��Žѕ���XZ�X�Eiq��K���|�'�Wi��
E2-�k�Zm��
�͞�+tj��p�o\m���jc\���ؠ_v�F�k;���$\O��JW!�zD3cZ�@���N�T�J!^c��<��+���)[sK�=�Sf���Tm���J>�i�tc���1��`ɱs
,,uO��zt� �Ү>j�6��xe�,�z��l�$jW�����n��g��~M��^�s-����}kDr���`ݶ��4��?��hT�G�߿E�Z�w����&��'��фAz��}�-��r�W�2=����ƛ�i�!��Ⱥu�J�8_d��z���9h�]��yi�A�6D�0H�R����g#��������>rS1�e�供�F����H�E[m�����Syc��糠�)��"��b�޻�0%�¤����
o70T&&�T�06�q�F��X`�V��u{1`&Xkx ��7�����|�v
2_�y��VL6z�xu��95�r�H'g�E�J�(\WY�T������T���kXM�bG�^kppڀ@�h�1�9�[���Ǽ�T<�/Oo�B =�iw����Ef��G�S�c<����������W�
�<�H�N����$�m�-=�;�*��].��v��n���&�V��D����_�{9��+��:����̶F0��|�1�9��p�9�*  �Rs�Ͱ�Ckl5ͫ�jGB��!��m�h
/��*г-�z�H�w�)Q����p��!� B�p�H֌˦eOŹ��������< ��Ǹ��[����uP��q�n�T���Lj����yrЙ-$�i��X����T~�R��4�xό~]��G��e�dÖnI��&b{�=�&��Bi�y���%|���E���H�=�k�~į_�6PӬ׫��D|~
M ;��BK�'�p����o:8��0]������ً   �&�k9��2�0�̟WtFy���t�>?GS��� W.����tG�R��$\V�'�����'�&��a����#�b�9�בȨ�yl�+J�M���rƠ�D�0H��B�w;��8\�!���.%��yc��~�9�X ;hq�)�&E�
�W��?�D�-:��,t�f柟.�-P�f�\˲�=S.�&
���X޳]�����Z��׸���������j�A(�]�����m�*U'"6��g��jw��

0 个答案:

没有答案