Эта статья является зеркальной статьёй машинного перевода, пожалуйста, нажмите здесь, чтобы перейти к оригиналу.

Вид: 16332|Ответ: 4

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

[Скопировать ссылку]
Опубликовано 08.12.2015 21:49:35 | | |
Это алгоритм блочной криптографии, но он использует много разных вариантов, и теперь в интернете есть конкретный исходный код, но этот код всё равно имеет определённую исследовательскую ценность, если вам это тоже интересно, вы можете прийти, общаться и учиться вместе. На самом деле, нет смысла давать вам полный код, но я всё равно прикрепляю полный адрес кода к http://www.2cto.com/kf/201501/369374.html
В ней также есть S-коробка, что очень важно, и используется в алгоритме DES, поэтому совет моего коллеги — чётко понять S-бокс алгоритма DES, чтобы я мог понять, о чём идёт речь в спецификации этого алгоритма SMS4. Спецификация не прилагается.





Предыдущий:Похоже, что это место давно не обновлялось, и я буду обновлять язык C каждый день в будущем.
Следующий:Язык C, полная версия видео
Опубликовано 08.12.2015 22:19:05 |

Введение в SMS4:

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

Основы алгоритма шифрования SMS4:



общественный класс SMS4 {

    приватный статический финальный int ENCRYPT = 1;
    приватный статический финал int DECRYPT = 0;
    публичный статический финальный интеллект ROUND = 32;
    приватный статический финальный int BLOCK = 16;

    приватный байт[] 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(байт[] Вход, байт[] Вывод, 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| Input[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

            середина = 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

            середина = 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) {
            Выход[j] = (байт) (x[3 - j / 4] >>> 24 и 0xFF);
            Выход[j + 1] = (байт) (x[3 - j / 4] >>> 16 и 0xFF);
            Выход[j + 2] = (байт) (x[3 - j / 4] >>> 8 и 0xFF);
            Выход[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] = Ключ[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];
        }
        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

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

            середина = 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; R < 16; r++) {
                mid = rk[r];
                rk[r] = rk[31 - r];
                rk[31 - r] = средний;
            }
        }
    }

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

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

        возврат 0;
    }
}

Включённый внешний интерфейс:

На основе этого базового класса основные интерфейсы выглядят следующим образом:



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

encode16(байт[], байт[]) — это интерфейс для шифрования 16-битных открытых и 16-битных ключей;
Частный статический байт[] декодирование16(байт[] шифр, ключ байт[]): — интерфейс для расшифровки 16-битного и 16-битного ключа;
Private static byte[] encode32(byte[] plain, byte[] key): Это интерфейс, который шифрует 32-битный открытый и 16-битный ключи.
Частный статический байт[] декодирование32(байт[] шифр, ключ байт[]): Это интерфейс для расшифровки 32-битного шифротекста и 16-битных ключей.
публичный статический байт[] encodeSMS4(byte[] plain, byte[] ключ): Это интерфейс, который шифрует открытый текст и 16-битные ключи с неограниченным количеством байт.
public static byte[] decodeSMS4(byte[] шифр, ключ byte[]): Это интерфейс для расшифровки шифротекста и 16-битных ключей с неограниченным количеством байт.
публичный статический Строковый декодSMS4toString(byte[] шифр, ключ byte[]): Это интерфейс для расшифровки неограниченного количества байт шифротекста и 16-битных ключей.
Код метода интерфейса:



публичный статический байт[] encodeSMS4(String plaintext, byte[] key) {
        если (открытый текст == null || plaintext.equals()) {
            возврат нуля;
        }
        для (int i = plaintext.getBytes().length % 16; Мне < 16; i++) {
            открытый текст += '';
        }
        
        возврат SMS4.encodeSMS4(plaintext.getBytes(), ключ);
    }
   
    /**
     * Шифрование SMS4 с неограниченной длиной открытого текста
     *
     * @param открытый текст
     * @param тональность
     * @return
     */
    публичный статический байт[] encodeSMS4(байт[] открытый текст, ключ byte[] {
        byte[] шифротекст = новый байт[plaintext.length];
        
        int k = 0;
        int plainLen = plaintext.length;
        в то время как (k + 16 <= plainLen) {
            byte[] 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
     */
    публичный статический байт[] decodeSMS4(байт[] шифротекст, ключ byte[] {
        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++) {
                открытый текст[k + i] = cellPlain;
            }
            
            k += 16;
        }
        
        вернуть открытый текст;
    }

    /**
     * Расшифровать для получения строк открытого текста
     * @param шифротекст
     * @param тональность
     * @return
     */
    публичный статический String decodeSMS4toString(byte[] шифротекст, ключ byte[]
        byte[] plaintext = новый байт[ciphertext.length];
        открытый текст = декодировать SMS4 (шифротекст, ключ);
        вернуть новую строку (открытый текст);
    }

    /**
     * Шифруется только 16-битный открытый текст
     *
     * @param открытый текст
     * @param тональность
     * @return
     */
    Частный статический байт[] encode16(byte[] открытый текст, ключ byte[] {
        byte[] шифр = новый байт[16];
        SMS4 sm4 = новый SMS4();
        sm4.sms4 (открытый текст, 16, ключ, шифр, ШИФРОВАНИЕ);

        возвратный шифр;
    }

    /**
     * Расшифровывается только 16-битный шифротекст
     *
     * @param открытый текст
     * @param тональность
     * @return
     */
    Частный статический байт[] декодирование16(байт[] шифротекст, ключ byte[] {
        byte[] plain = новый байт[16];
        SMS4 sm4 = новый SMS4();
        sm4.sms4 (шифротекст, 16, ключ, простой, РАСШИФРОВАН);

        возврат на равнину;
    }
Я не буду вводить только 32-битное открытое шифрование, которое очень похоже на метод только 16-битного открытого текста.


Базовый алгоритм шифрования и расшифровки без ограничения длины открытого текста основан на этой основе шифрования и расшифровки всего 16 бит. Для открытого текста больше 16 бит здесь используется шифрование пакетов. Если вы столкнётесь с открытым текстом, например 30 бит, которые нельзя делить на 16, один из способов заполнить его — довести до того, чтобы он делился на 16. В принципе, только наименьшее число можно разделить на 16, конечно, если вы довольны, неважно, увеличите ли вы его, ведь это завершающий символ.

Шифрование пакетов — это шифрование каждого 16-битного открытого текста один раз, а затем сборка зашифрованного 16-битного шифротекста в новый шифротекст. В процессе расшифровки он также делится на одну 16-битную часть, после чего несколько из этих расшифрованных открытых текстов собираются в новый открытый текст.



Демонстрация использования:



Ключ
        byte[] key = { 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(
результат расшифровки (возвращаемый байт[]) :);
        printBit(deOut);

        String deOutStr = SMS4.decodeSMS4toString(enOut, key);
        System.out.println(
Расшифровать результат (вернуть строку):
+ deOutStr);
 Хозяин| Опубликовано 08.12.2015 22:25:41 |
Сяо Чжажа Опубликовано 2015-12-8 22:19
Введение в SMS4:

Этот алгоритм является алгоритмом группировки. Алгоритм имеет длину пакета 128 бит, а длину ключа — 128 бит, что составляет 16 байт. ...

Ты копируешь лицо внутри? Я несколько раз запускал этот алгоритм на компьютере, но до сих пор не знаком с отладкой на C# в Java, возможно, не знаю всех его шагов в деталях и ещё не разобрался с принципом его работы. Java, знаешь, как отладить каждую переменную?
Опубликовано 08.12.2015 22:40:48 |

Это должно быть для установки точки остановки, ключи F5 и клавиши F6 для одноступенчатого отладки, F5 — это step in, то есть ввести строчный код для выполнения, F6 — step over, то есть выполнить строчный код и перейти к следующей строке
 Хозяин| Опубликовано 08.12.2015 23:07:37 |
Опубликовано 2015-12-8 22:40
Это должно быть для установки точки остановки, ключи Myeclipse Breakpoint F5 и F6 — это одношаговая отладка, F5 — это шаг, то есть ввести код этой строки для выполнения ...

Я точно знаю, но не знаю его конкретного процесса и не знаю, когда и куда прийду к какому-то этапу спецификации. Было бы здорово, если бы ты понял
Отказ:
Всё программное обеспечение, программные материалы или статьи, публикуемые Code Farmer Network, предназначены исключительно для учебных и исследовательских целей; Вышеуказанный контент не должен использоваться в коммерческих или незаконных целях, иначе пользователи несут все последствия. Информация на этом сайте взята из Интернета, и споры по авторским правам не имеют отношения к этому сайту. Вы должны полностью удалить вышеуказанный контент с компьютера в течение 24 часов после загрузки. Если вам нравится программа, пожалуйста, поддержите подлинное программное обеспечение, купите регистрацию и получите лучшие подлинные услуги. Если есть нарушение, пожалуйста, свяжитесь с нами по электронной почте.

Mail To:help@itsvse.com