Тази статия е огледална статия за машинен превод, моля, кликнете тук, за да преминете към оригиналната статия.

Изглед: 16332|Отговор: 4

[Алгоритъм] SMS4 алгоритъм, който е алгоритъм за симетрична блокова криптография

[Копирай линк]
Публикувано в 8.12.2015 г. 21:49:35 ч. | | |
Това е алгоритъм за блокова криптография, но той използва много неща, и сега има специфичен изходен код в интернет, но този код все пак има определена изследователска стойност – ако и вие се интересувате от това, можете да влезете, да комуникирате и да учите заедно. Всъщност няма смисъл да ти давам пълен код, но все пак прикачвам пълния адрес на кода към http://www.2cto.com/kf/201501/369374.html
Има и S кутия в нея, която е много важна и се използва в алгоритъма DES, така че предложението на колегата ми е да разбера ясно S кутията на алгоритъма DES, за да мога да разбера за какво говори спецификацията в този алгоритъм SMS4? Спецификацията не е приложена.





Предишен:Изглежда, че това място не е обновявано отдавна и ще обновявам езика C всеки ден в бъдеще.
Следващ:Език C, пълно видео
Публикувано в 8.12.2015 г. 22:19:05 ч. |

Въведение в SMS4:

Този алгоритъм е алгоритъм за групиране. Алгоритъмът има дължина на пакета от 128 бита и дължина на ключа 128 бита, което е 16 байта. И алгоритъмът за криптиране, и алгоритъмът за разширяване на ключа приемат структура на нелинейна итерация от 32 рунда. Алгоритъмът за декриптиране има същата структура като алгоритъма за криптиране, с изключение на това, че редът на използване на кръглия ключ е обърнат, а ключът за колелото за декриптиране е обратният ред на ключа за криптиращото колело. Във всички базови класове на SMS4 ще видите, че основните функции на криптиране и декриптиране са еднакви, но е необходим int-тип флаг бит, за да се определи дали е криптиран или декриптиран.

Основи на алгоритъма за криптиране на SMS4:



публичен клас SMS4 {

    private static final int ENCRYPT = 1;
    частен статичен финал int DECRYPT = 0;
    публичен статичен финален интелект ROUND = 32;
    частен статичен финален int BLOCK = 16;

    private byte[] Sbox = { (байт) 0xd6, (байт) 0x90, (байт) 0xe9, (байт) 0xfe,
            (байт) 0xcc, (байт) 0xe1, 0x3d, (байт) 0xb7, 0x16, (байт) 0xb6,
            0x14, (байт) 0xc2, 0x28, (байт) 0xfb, 0x2c, 0x05, 0x2b, 0x67,
            (байт) 0x9a, 0x76, 0x2a, (байт) 0xbe, 0x04, (байт) 0xc3,
            (байт) 0xaa, 0x44, 0x13, 0x26, 0x49, (байт) 0x86, 0x06,
            (байт) 0x99, (байт) 0x9c, 0x42, 0x50, (байт) 0xf4, (байт) 0x91,
            (байт) 0xef, (байт) 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43,
            (байт) 0xed, (байт) 0xcf, (байт) 0xac, 0x62, (байт) 0xe4,
            (байт) 0xb3, 0x1c, (байт) 0xa9, (байт) 0xc9, 0x08, (байт) 0xe8,
            (байт) 0x95, (байт) 0x80, (байт) 0xdf, (байт) 0x94, (байт) 0xfa,
            0x75, (байт) 0x8f, 0x3f, (байт) 0xa6, 0x47, 0x07, (байт) 0xa7,
            (байт) 0xfc, (байт) 0xf3, 0x73, 0x17, (байт) 0xba, (байт) 0x83,
            0x59, 0x3c, 0x19, (байт) 0xe6, (байт) 0x85, 0x4f, (байт) 0xa8,
            0x68, 0x6b, (байт) 0x81, (байт) 0xb2, 0x71, 0x64, (байт) 0xda,
            (байт) 0x8b, (байт) 0xf8, (байт) 0xeb, 0x0f, 0x4b, 0x70, 0x56,
            (байт) 0x9d, 0x35, 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, (байт) 0xd1,
            (байт) 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, (байт) 0x87,
            (байт) 0xd4, 0x00, 0x46, 0x57, (байт) 0x9f, (байт) 0xd3, 0x27,
            0x52, 0x4c, 0x36, 0x02, (байт) 0xe7, (байт) 0xa0, (байт) 0xc4,
            (байт) 0xc8, (байт) 0x9e, (байт) 0xea, (байт) 0xbf, (байт) 0x8a,
            (байт) 0xd2, 0x40, (байт) 0xc7, 0x38, (байт) 0xb5, (байт) 0xa3,
            (байт) 0xf7, (байт) 0xf2, (байт) 0xce, (байт) 0xf9, 0x61, 0x15,
            (байт) 0xa1, (байт) 0xe0, (байт) 0xae, 0x5d, (байт) 0xa4,
            (байт) 0x9b, 0x34, 0x1a, 0x55, (байт) 0xad, (байт) 0x93, 0x32,
            0x30, (байт) 0xf5, (байт) 0x8c, (байт) 0xb1, (байт) 0xe3, 0x1d,
            (байт) 0xf6, (байт) 0xe2, 0x2e, (байт) 0x82, 0x66, (байт) 0xca,
            0x60, (байт) 0xc0, 0x29, 0x23, (байт) 0xab, 0x0d, 0x53, 0x4e, 0x6f,
            (байт) 0xd5, (байт) 0xdb, 0x37, 0x45, (байт) 0xde, (байт) 0xfd,
            (байт) 0x8e, 0x2f, 0x03, (байт) 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b,
            0x51, (байт) 0x8d, 0x1b, (байт) 0xaf, (байт) 0x92, (байт) 0xbb,
            (байт) 0xdd, (байт) 0xbc, 0x7f, 0x11, (байт) 0xd9, 0x5c, 0x41,
            0x1f, 0x10, 0x5a, (байт) 0xd8, 0x0a, (байт) 0xc1, 0x31,
            (байт) 0x88, (байт) 0xa5, (байт) 0xcd, 0x7b, (байт) 0xbd, 0x2d,
            0x74, (байт) 0xd0, 0x12, (байт) 0xb8, (байт) 0xe5, (байт) 0xb4,
            (байт) 0xb0, (байт) 0x89, 0x69, (байт) 0x97, 0x4a, 0x0c,
            (байт) 0x96, 0x77, 0x7e, 0x65, (байт) 0xb9, (байт) 0xf1, 0x09,
            (байт) 0xc5, 0x6e, (байт) 0xc6, (байт) 0x84, 0x18, (байт) 0xf0,
            0x7d, (байт) 0xec, 0x3a, (байт) 0xdc, 0x4d, 0x20, 0x79,
            (байт) 0xee, 0x5f, 0x3e, (байт) 0xd7, (байт) 0xcb, 0x39, 0x48 };

    private int[] CK = { 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
            0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9, 0xe0e7eef5,
            0xfc030a11, 0x181f262d, 0x343b4249, 0x50575e65, 0x6c737a81,
            0x888f969d, 0xa4abb2b9, 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d,
            0x141b2229, 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
            0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209, 0x10171e25,
            0x2c333a41, 0x484f565d, 0x646b7279 };

    private int Rotl(int x, int y) {
        връщане x << y | x >>> (32 - y);
    }

    private int ByteSub(int A) {
        return (Sbox[A >>> 24 & 0xFF] и 0xFF) << 24
                | (Sbox[A >>> 16 & 0xFF] и 0xFF) << 16
                | (Sbox[A >>> 8 & 0xFF] и 0xFF) << 8 | (Sbox[A & 0xFF] и 0xFF);
    }

    private int L1(int B) {
        return B ^ Rotl(B, 2) ^ Rotl(B, 10) ^ Rotl(B, 18) ^ Rotl(B, 24);
        връщане B^(B<<2|B>>>30)^(B<<10|B>>>22)^(B<<18|B>>>14)^(B<<24|B>>>8);
    }

    private int L2(int B) {
        връщане B ^ Rotl(B, 13) ^ Rotl(B, 23);
        връщане B^(B<<13|B>>>19)^(B<<23|B>>>9);
    }

    void SMS4Crypt(byte[] Вход, байт[] Изход, int[] rk) {
        вътрешен вход R, MID, x0, X1, X2, X3;
        int[] x = нов int[4];
        int[] tmp = нов int[4];
        за (int i = 0; I < 4; i++) {
            tmp[0] = Вход[0 + 4 * i] & 0xff;
            tmp[1] = Вход[1 + 4 * i] & 0xff;
            tmp[2] = Вход[2 + 4 * i] & 0xff;
            tmp[3] = Вход[3 + 4 * i] & 0xff;
            x= tmp[0] << 24 | tmp[1] << 16 | tmp[2] << 8 | tmp[3];
            x=(Вход[0+4*i]<<24| Вход[1+4*i]<<16| Вход[2+4*i]<<8| Вход[3+4*i]);
        }
        за (r = 0; r < 32; r += 4) {
            средно = x[1] ^ x[2] ^ x[3] ^ rk[r + 0];
            mid = ByteSub(mid);
            x[0] = x[0] ^ L1(среда); x4

            mid = x[2] ^ x[3] ^ x[0] ^ rk[r + 1];
            mid = ByteSub(mid);
            x[1] = x[1] ^ L1(среда); x5

            средно = x[3] ^ x[0] ^ x[1] ^ rk[r + 2];
            mid = ByteSub(mid);
            x[2] = x[2] ^ L1(среда); x6

            mid = x[0] ^ x[1] ^ x[2] ^ rk[r + 3];
            mid = ByteSub(mid);
            x[3] = x[3] ^ L1(среда); x7
        }

        Обратна страна
        за (int j = 0; j < 16; j += 4) {
            Output[j] = (байт) (x[3 - j / 4] >>> 24 & 0xFF);
            Output[j + 1] = (байт) (x[3 - j / 4] >>> 16 & 0xFF);
            Изход[j + 2] = (байт) (x[3 - j / 4] >>> 8 и 0xFF);
            Output[j + 3] = (байт) (x[3 - j / 4] & 0xFF);
        }
    }

    private void SMS4KeyExt(byte[] Key, int[] rk, int CryptFlag) {
        Вътрешен удар, среден удар;
        int[] x = нов int[4];
        int[] tmp = нов int[4];
        за (int i = 0; I < 4; i++) {
            tmp[0] = Key[0 + 4 * i] & 0xFF;
            tmp[1] = Key[1 + 4 * i] & 0xff;
            tmp[2] = Ключ[2 + 4 * i] & 0xff;
            tmp[3] = Ключ[3 + 4 * i] & 0xff;
            x= tmp[0] << 24 | tmp[1] << 16 | tmp[2] << 8 | tmp[3];
            x=Ключ[0+4*i]<<24| Ключ[1+4*i]<<16| Key[2+4*i]<<8| Ключ[3+4*i];
        }
        x[0] ^= 0xa3b1bac6;
        x[1] ^= 0x56aa3350;
        x[2] ^= 0x677d9197;
        x[3] ^= 0xb27022dc;
        за (r = 0; r < 32; r += 4) {
            средно = x[1] ^ x[2] ^ x[3] ^ CK[r + 0];
            mid = ByteSub(mid);
            rk[r + 0] = x[0] ^= L2(среда); rk0=K4

            mid = x[2] ^ x[3] ^ x[0] ^ CK[r + 1];
            mid = ByteSub(mid);
            rk[r + 1] = x[1] ^= L2(среда); rk1=K5

            mid = x[3] ^ x[0] ^ x[1] ^ CK[r + 2];
            mid = ByteSub(mid);
            rk[r + 2] = x[2] ^= L2(среда); rk2=K6

            средно = x[0] ^ x[1] ^ x[2] ^ CK[r + 3];
            mid = ByteSub(mid);
            rk[r + 3] = x[3] ^= L2(среда); rk3=K7
        }

        Декриптирайте реда на ключа на колелото: rk31, rk30,...,rk0
        ако (CryptFlag == ДЕКРИПТ) {
            за (r = 0; р < 16; r++) {
                mid = rk[r];
                rk[r] = rk[31 - r];
                RK[31 - R] = Мид;
            }
        }
    }

    public int sms4(byte[] in, int inLen, byte[] key, byte[] out, int CryptFlag) {
        int точка = 0;
        int[] round_key = нов int[ROUND];
        int[] round_key={0};
        SMS4KeyExt(ключ, round_key, CryptFlag);
        байт[] вход = нов байт[16];
        байт[] изход = нов байт[16];

        докато (inLen >= БЛОК) {
            input = Arrays.copyOfRange(in, point, точка + 16);
            output=Arrays.copyOfRange(out, point, point+16);
            SMS4Crypt(вход, изход round_key);
            System.arraycopy (изход, 0, изход, точка, БЛОК);
            inLen -= БЛОК;
            точка += БЛОК;
        }

        return 0;
    }
}

Пакетиран външен интерфейс:

Въз основа на този основен клас, основните интерфейси са следните:



частен статичен байт[] encode16(byte[] plain, byte[] key);
частен статичен байт[] декодиране 16(байт[] шифър, ключ byte[] ]
частен статичен байт[] encode32(byte[] plain, byte[] key);
частен статичен байт[] декодиране32(байт[] шифър, ключ байт[]);
публичен статичен байт[] encodeSMS4(byte[] обикновен, byte[] ключ);
публичен статичен байт[] декодира SMS4(байт[] шифър, ключ байт[]);
публичен статичен String декодиране SMS4toString(байт[] шифър, байт[] ключ);

encode16(байт[], байт[]) е интерфейс за криптиране на 16-битов открит текст и 16-битови ключове;
Частен статичен байт[] декодиране16(байт[] шифър, байт[] ключ): е интерфейс за декриптиране на 16-битов 16-битов шифротекст и 16-битов ключ;
Private static byte[] encode32(byte[] plain, byte[] key): Това е интерфейс, който криптира 32-битов открит текст и 16-битови ключове.
Частен статичен байт[] декодиране32(байт[] шифър, байт[] ключ): Това е интерфейс за декриптиране на 32-битов шифротекст и 16-битови ключове.
публичен статичен байт[] encodeSMS4(байт[] обикновен, байт[] ключ): Това е интерфейс, който криптира открит текст и 16-битови ключове с неограничен брой байтове.
публичен статичен байт[] декодиране SMS4(байт[] шифър, байт[] ключ): Това е интерфейс за декриптиране на шифротекст и 16-битови ключове с неограничен брой байтове.
публичен статичен String decodeSMS4toString(byte[] шифър, byte[] ключ): Това е интерфейс за декриптиране на неограничени байтове шифротекст и 16-битови ключове.
Код на метода на интерфейса:



публичен статичен байт[] encodeSMS4(Низов открит текст, байт[] ключ) {
        ако (plaintext == null || plaintext.equals()) {
            return null;
        }
        за (int i = plaintext.getBytes().length % 16; < на 16; i++) {
            открит текст += '';
        }
        
        връща SMS4.encodeSMS4(plaintext.getBytes(), ключ);
    }
   
    /**
     * SMS4 криптиране с неограничена дължина на открития текст
     *
     * @param открит текст
     * @param тоналност
     * @return
     */
    публичен статичен байт[] encodeSMS4(байт[] открит текст, байт[] ключ) {
        byte[] ciphertext = нов байт[plaintext.length];
        
        int k = 0;
        int plainLen = plaintext.length;
        докато (k + 16 <= plainLen) {
            байт[] cellPlain = нов байт[16];
            за (int i = 0; < на 16; i++) {
                cellPlain= открит текст[k + i];
            }
            byte[] cellCipher = encode16(cellPlain, key);
            за (int i = 0; i < cellCipher.length; i++) {
                ciphertext[k + i] = cellCipher;
            }
            
            k += 16;
        }

        връщане на шифротекст;
    }

    /**
     * Декриптиране на SMS4 без ограничение на дължината на открития текст
     *
     * @param шифротекст
     * @param тоналност
     * @return
     */
    публичен статичен байт[] декодиране SMS4(байт[] шифротекст, ключ байт[] {
        byte[] plaintext = нов байт[ciphertext.length];
        
        int k = 0;
        int cipherLen = ciphertext.length;
        докато (k + 16 <= cipherLen) {
            byte[] cellCipher = нов байт[16];
            за (int i = 0; < на 16; i++) {
                cellCipher= шифротекст[k + i];
            }
            byte[] cellPlain = decode16(cellCipher, ключ);
            за (int i = 0; i < cellPlain.length; i++) {
                plaintext[k + i] = cellPlain;
            }
            
            k += 16;
        }
        
        върни открит текст;
    }

    /**
     * Декриптиране за получаване на низове от открит текст
     * @param шифротекст
     * @param тоналност
     * @return
     */
    публичен статичен String decodeSMS4toString(byte[] ciphertext, byte[] key) {
        byte[] plaintext = нов байт[ciphertext.length];
        открит текст = декодиране SMS4 (шифротекст, ключ);
        връщане на нов String (открит текст);
    }

    /**
     * Криптиран е само 16-битов открит текст
     *
     * @param открит текст
     * @param тоналност
     * @return
     */
    Частен статичен байт[] encode16(byte[] plaintext, byte[] key) {
        byte[] cipher = нов байт[16];
        SMS4 sm4 = нов SMS4();
        sm4.sms4 (открит текст, 16, ключ, шифр, ENCRYPT);

        шифър за връщане;
    }

    /**
     * Само 16-битов шифротекст се декриптира
     *
     * @param открит текст
     * @param тоналност
     * @return
     */
    Частен статичен байт[] декодиране16(байт[] шифротекст, ключ байт[] {
        байт[] plain = нов байт[16];
        SMS4 sm4 = нов SMS4();
        sm4.sms4(шифротекст, 16, ключ, обикновен, ДЕКРИПТ);

        връщане на равнина;
    }
Няма да въвеждам само 32-битово криптиране на открит текст, което е много подобно на метода с само 16-битов открит текст.


Основният алгоритъм за криптиране и декриптиране без ограничаване на дължината на открития текст се основава на криптиране и декриптиране само на 16 бита. За открит текст по-голям от 16 бита тук се използва пакетно криптиране. Ако срещнеш открит текст като 30 бита, които не могат да се делят на 16, начинът да го запълниш е да го компенсираш докато стане делимо на 16. По принцип само най-малкото число може да се дели на 16, разбира се, ако сте доволни, няма значение дали го направите по-голямо, защото това е символът за затваряне.

Пакетното криптиране означава да се криптира всеки 16-битов открит текст веднъж и след това криптираният 16-битов шифротекст да се сглоби отново в нов шифротекст. В процеса на декриптиране тя също се разделя на една 16-битова част, след което няколко от тези декриптирани открити текстове се сглобяват отново в нов открит текст.



Демонстрация на употреба:



Ключ
        byte[] ключ = { 0x01, 0x23, 0x45, 0x67, (байт) 0x89, (байт) 0xab,
                (байт) 0xcd, (байт) 0xef, (байт) 0xfe, (байт) 0xdc,
                (байт) 0xba, (байт) 0x98, 0x76, 0x54, 0x32, 0x10 };

        String newString = Кодиране, здравейте!; Обикновен текст
        
        byte[] enOut = SMS4.encodeSMS4(newString, key);
        ако (enOut == null) {
            връщане;
        }
        
        System.out.println(резултат от криптиране:);
        printBit(enOut);

        byte[] deOut = SMS4.decodeSMS4(enOut, ключ);
        System.out.println(
резултат от декриптиране (return byte[]) :);
        printBit(deOut);

        String deOutStr = SMS4.decodeSMS4toString(enOut, key);
        System.out.println(
Декриптирайте резултата (връщане на низ):
+ deOutStr);
 Хазяин| Публикувано в 8.12.2015 г. 22:25:41 ч. |
Xiao Zhazha Публикувано на 2015-12-8 22:19
Въведение в SMS4:

Този алгоритъм е алгоритъм за групиране. Алгоритъмът има дължина на пакета от 128 бита и дължина на ключа 128 бита, което е 16 байта. ...

Копираш ли лицето вътре? Пускал съм този алгоритъм на компютъра няколко пъти, но все още не съм запознат с C# в Java дебъгването и може би не знам всяка негова стъпка в детайли, и все още не съм разбрал принципа на неговите работни детайли. Java, знаеш ли как да дебъгваш всяка променлива?
Публикувано в 8.12.2015 г. 22:40:48 ч. |

Трябва да се зададе точката на прекъсване, ключът F5 и F6 за една стъпка за отстраняване на грешки, F5 е step in, тоест въвеждане на редовия код за изпълнение, F6 е step over, тоест изпълване на редовия код, прескачане към следващия ред
 Хазяин| Публикувано в 8.12.2015 г. 23:07:37 ч. |
Публикувано на 2015-12-8 22:40
Трябва да се зададе точката на прекъсване, ключ F5 и ключ F6 за миеклипс са едностепенно отстраняване на грешки, F5 е стъпка в това, тоест въвеждане на кода на този ред, за да се изпълни ...

Определено знам, но не знам конкретния му процес и не знам кога и къде ще стигна до кой етап в спецификацията. Би било хубаво, ако разбереш
Отричане:
Целият софтуер, програмни материали или статии, публикувани от Code Farmer Network, са само за учебни и изследователски цели; Горното съдържание не трябва да се използва за търговски или незаконни цели, в противен случай потребителите ще понесат всички последствия. Информацията на този сайт идва от интернет, а споровете за авторски права нямат нищо общо с този сайт. Трябва напълно да изтриете горното съдържание от компютъра си в рамките на 24 часа след изтеглянето. Ако ви харесва програмата, моля, подкрепете оригинален софтуер, купете регистрация и получете по-добри услуги. Ако има нарушение, моля, свържете се с нас по имейл.

Mail To:help@itsvse.com