Ten artykuł jest lustrzanym artykułem tłumaczenia maszynowego, kliknij tutaj, aby przejść do oryginalnego artykułu.

Widok: 16332|Odpowiedź: 4

[Algorytm] Algorytm SMS4, który jest symetrycznym algorytmem kryptografii blokowej

[Skopiuj link]
Opublikowano 08.12.2015 21:49:35 | | |
To algorytm kryptografii blokowej, ale używa on wielu różnych rzeczy, a teraz w Internecie jest konkretny kod źródłowy, ale ten kod nadal ma wartość badawczą, jeśli również jesteś tym zainteresowany, możesz wejść, komunikować się i uczyć razem. W rzeczywistości nie ma sensu podawać ci kompletnego kodu, ale i tak dołączam pełny adres kodu do http://www.2cto.com/kf/201501/369374.html
Jest też w niej pole S, które jest bardzo ważne i jest używane w algorytmie DES, więc sugestia mojego kolegi jest taka, żebym jasno zrozumiał pole S algorytmu DES, żebym mógł wiedzieć, o czym mówi specyfikacja w algorytmie SMS4. Specyfikacja nie jest dołączona.





Poprzedni:Wygląda na to, że to miejsce nie było aktualizowane od dawna, a ja będę codziennie aktualizować język C.
Następny:Język C, pełna wersja wideo
Opublikowano 08.12.2015 22:19:05 |

Wprowadzenie do SMS4:

Ten algorytm jest algorytmem grupowania. Algorytm ma długość pakietu 128 bitów i długość klucza 128 bitów, co daje 16 bajtów. Zarówno algorytm szyfrowania, jak i algorytm rozszerzania klucza przyjmują 32-rundową nieliniową strukturę iteracji. Algorytm deszyfrowania ma taką samą strukturę jak algorytm szyfrowania, z tą różnicą, że kolejność użycia klucza rundy jest odwrócona, a klucz koła deszyfrującego jest odwróconą kolejnością klucza koła szyfrującego. We wszystkich podstawowych klasach SMS4 zauważysz, że podstawowe funkcje szyfrowania i deszyfrowania są takie same, ale potrzebny jest bit flagi typu int, aby określić, czy jest szyfrowany czy odszyfrowany.

Podstawy algorytmu szyfrowania SMS4:



public class SMS4 {

    prywatny statyczny final int ENCRYPT = 1;
    prywatny statyczny final int DECRYPT = 0;
    publiczny finał statyczny inter RUNDA = 32;
    prywatny statyczny końcowy int BLOCK = 16;

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

    prywatny 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) {
        zwróć 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);
        return B^(B<<2|B>>>30)^(B<<10|B>>>22)^(B<<18|B>>>14)^(B<<24|B>>>8);
    }

    prywatny int L2(int B) {
        return B ^ Rotl(B, 13) ^ Rotl(B, 23);
        return B^(B<<13|B>>>19)^(B<<23|B>>>9);
    }

    void SMS4Crypt(byte[] Input, byte[] Output, int[] rk) {
        int r, mid, x0, x1, x2, x3;
        int[] x = nowy int[4];
        int[] tmp = nowy int[4];
        dla (int i = 0; Mam < 4; i++) {
            tmp[0] = Input[0 + 4 * i] & 0xff;
            tmp[1] = Input[1 + 4 * i] & 0xff;
            tmp[2] = Input[2 + 4 * i] & 0xff;
            tmp[3] = Input[3 + 4 * i] & 0xff;
            x= tmp[0] << 24 | TMP[1] << 16 | TMP[2] << 8 | TMP[3];
            x=(Input[0+4*i]<<24| Input[1+4*i]<<16| Input[2+4*i]<<8| Input[3+4*i]);
        }
        dla (r = 0; r < 32; r += 4) {
            środek = x[1] ^ x[2] ^ x[3] ^ rk[r + 0];
            mid = ByteSub(mid);
            x[0] = x[0] ^ L1(środek); x4

            środek = x[2] ^ x[3] ^ x[0] ^ rk[r + 1];
            mid = ByteSub(mid);
            x[1] = x[1] ^ L1(środek); x5

            mid = x[3] ^ x[0] ^ x[1] ^ rk[r + 2];
            mid = ByteSub(mid);
            x[2] = x[2] ^ L1(środek); x6

            środek = x[0] ^ x[1] ^ x[2] ^ rk[r + 3];
            mid = ByteSub(mid);
            x[3] = x[3] ^ L1(środek); x7
        }

        Rewers
        dla (int j = 0; j < 16; j += 4) {
            Wyjście[j] = (bajt) (x[3 - j / 4] >>> 24 & 0xFF);
            Wyjście[j + 1] = (bajt) (x[3 - j / 4] >>> 16 & 0xFF);
            Wyjście[j + 2] = (bajt) (x[3 - j / 4] >>> 8 & 0xFF);
            Wyjście[j + 3] = (bajt) (x[3 - j / 4] & 0xFF);
        }
    }

    private void SMS4KeyExt(byte[] Key, int[] rk, int CryptFlag) {
        int r, mid;
        int[] x = nowy int[4];
        int[] tmp = nowy int[4];
        dla (int i = 0; Mam < 4; i++) {
            tmp[0] = Klucz[0 + 4 * i] & 0xFF;
            tmp[1] = Key[1 + 4 * i] & 0xff;
            tmp[2] = Klucz[2 + 4 * i] & 0xff;
            tmp[3] = Klucz[3 + 4 * i] & 0xff;
            x= tmp[0] << 24 | TMP[1] << 16 | TMP[2] << 8 | TMP[3];
            x=Key[0+4*i]<<24| Key[1+4*i]<<16| Key[2+4*i]<<8| Klucz[3+4*i];
        }
        x[0] ^= 0xa3b1bac6;
        x[1] ^= 0x56aa3350;
        x[2] ^= 0x677d9197;
        x[3] ^= 0xb27022dc;
        dla (r = 0; r < 32; r += 4) {
            środek = x[1] ^ x[2] ^ x[3] ^ CK[r + 0];
            mid = ByteSub(mid);
            rk[r + 0] = x[0] ^= L2(środek); rk0=K4

            środek = x[2] ^ x[3] ^ x[0] ^ CK[r + 1];
            mid = ByteSub(mid);
            rk[r + 1] = x[1] ^= L2(środek); rk1=K5

            środek = x[3] ^ x[0] ^ x[1] ^ CK[r + 2];
            mid = ByteSub(mid);
            rk[r + 2] = x[2] ^= L2(środek); rk2=K6

            środek = x[0] ^ x[1] ^ x[2] ^ CK[r + 3];
            mid = ByteSub(mid);
            rk[r + 3] = x[3] ^= L2(środek); rk3=K7
        }

        Odszyfrowanie kolejności koła: rk31, rk30,...,rk0
        if (CryptFlag == DECRYPT) {
            dla (r = 0; r < 16; r++) {
                mid = rk[r];
                rk[r] = rk[31 - r];
                rk[31 - R] = środek;
            }
        }
    }

    public int sms4(byte[] in, int inLen, byte[] key, byte[] out, int CryptFlag) {
        int point = 0;
        int[] round_key = nowy int[ROUND];
        int[] round_key={0};
        SMS4KeyExt(key, round_key, CryptFlag);
        bajt[] wejście = nowy bajt[16];
        bajt[] output = nowy bajt[16];

        while (inLen >= BLOCK) {
            input = Arrays.copyOfRange(in, point, point + 16);
            output=Arrays.copyOfRange(out, point, point+16);
            SMS4Crypt (wejście, wyjście, round_key);
            System.arraycopy(output, 0, out, point, BLOCK);
            inLen -= BLOK;
            punkt += BLOK;
        }

        return 0;
    }
}

Zintegrowany zewnętrzny interfejs:

Na podstawie tej podstawowej klasy główne interfejsy są następujące:



prywatny bajt statyczny[] encode16(byte[] plain, bajt[] key);
prywatny bajt statyczny[] decode16(bajt[] szyfr, bajt[] klucz);
prywatny bajt statyczny[] encode32(bajt[] prosty, bajt[] klucz);
prywatny bajt statyczny[] decode32(bajt[] szyfr, bajt[] klucz);
publiczny bajt statyczny[] kodować SMS4(bajt[] prosty, bajt[] klucz);
publiczny bajt statyczny[] dekodować SMS4(bajt[] szyfr, bajt[] klucz);
publiczny statyczny String dekoduje SMS4toString(byte[] szyfr, bajt[] klucz);

encode16(byte[], byte[]) to interfejs do szyfrowania kluczy jawnych 16-bitowego i 16-bitowego;
prywatny statyczny bajt[] decode16(byte[] szyfr, bajt[] klucz): to interfejs do odszyfrowania 16-bitowego szyfrogramu i klucza 16-bitowego;
prywatny bajt statyczny[] encode32(byte[] prosty, bajt[] klucz): To interfejs szyfrujący klucze zwykłe 32-bitowe i 16-bitowe.
prywatny statyczny bajt[] decode32(byte[] szyfr, bajt[] klucz): To interfejs do odszyfrowywania 32-bitowego szyfrogramu i kluczy 16-bitowych.
public static byte[] encodeSMS4(byte[] plain, byte[] key): To interfejs szyfrujący tekst jawny i klucze 16-bitowe z nieograniczoną liczbą bajtów.
public static byte[] decodeSMS4(byte[] szyfr, bajt[] klucz): To interfejs do odszyfrowywania tekstów zaszyfrowanych i kluczy 16-bitowych z nieograniczoną liczbą bajtów.
publiczny statyczny String dekoduje SMS4toString(byte[] szyfr, bajt[] klucz): To interfejs do odszypywania nieograniczonej liczby bajtów szyfrogramu i kluczy 16-bitowych.
Kod metody interfejsu:



public static byte[] encodeSMS4(String plaintext, byte[] key) {
        if (plaintext == null || plaintext.equals()) {
            return null;
        }
        for (int i = jawny tekst.getBytes().długość % 16; < 16 lat; i++) {
            tekst jawny += '';
        }
        
        return SMS4.encodeSMS4(plaintext.getBytes(), klucz);
    }
   
    /**
     * Szyfrowanie SMS4 z nieograniczoną długością tekstu jawnego
     *
     * @param tekst jawny
     * @param klucz
     * @return
     */
    publiczny bajt statyczny[] enkoduj SMS4(bajt[] tekst jawny, bajt[] klucz) {
        bajt[] szyfrogram = nowy bajt[plaintext.length];
        
        int k = 0;
        int plainLen = jawny tekst.długość;
        while (k + 16 <= plainLen) {
            bajt[] cellPlain = nowy bajt[16];
            dla (int i = 0; < 16 lat; i++) {
                cellPlain= tekst jawny[k + i];
            }
            bajt[] cellCipher = encode16(cellPlain, key);
            dla (int i = 0; i < cellCipher.length; i++) {
                Szyfr [k + i] = cellCipher;
            }
            
            k += 16;
        }

        zwróć szyfrogram;
    }

    /**
     * Deszyfrowanie SMS4 bez ograniczenia długości tekstu jawnego
     *
     * @param szyfrogram
     * @param klucz
     * @return
     */
    public static byte[] dekodować SMS4(byte[] szyfr, bajt[] klucz) {
        bajt[] tekst jawny = nowy bajt[szyfrowany tekst.długość];
        
        int k = 0;
        int cipherLen = tekst szyfrowy. długość;
        while (k + 16 <= cipherLen) {
            bajt[] cellCipher = nowy bajt[16];
            dla (int i = 0; < 16 lat; i++) {
                cellCipher= tekst szyfrogram[k + i];
            }
            bajt[] cellPlain = decode16(cellCipher, key);
            dla (int i = 0; i < komórkaPlain.length; i++) {
                jawny tekst[k + i] = komórkaPlain;
            }
            
            k += 16;
        }
        
        zwróć tekst jawny;
    }

    /**
     * Deszyfruj, aby uzyskać ciągi tekstu jawnego
     * @param szyfrogram
     * @param klucz
     * @return
     */
    public static String dekoduj SMS4toString(byte[] szyfru, bajt[] key) {
        bajt[] tekst jawny = nowy bajt[szyfrowany tekst.długość];
        tekst jawny = dekodować SMS4(szyfrogram, klucz);
        zwróć nowy String(tekst jawny);
    }

    /**
     * Szyfrowany jest tylko 16-bitowy tekst jawny
     *
     * @param tekst jawny
     * @param klucz
     * @return
     */
    Prywatny bajt statyczny[] encode16(byte[] tekst jawny, bajt[] klucz) {
        bajt[] szyfr = nowy bajt[16];
        SMS4 sm4 = nowy SMS4();
        sm4.sms4 (tekst jawny, 16, klucz, szyfr, ENCRYPT);

        szyfr zwrotny;
    }

    /**
     * Odszyfrowuje się tylko 16-bitowy szyfrogram
     *
     * @param tekst jawny
     * @param klucz
     * @return
     */
    Prywatny bajt statyczny[] decode16(byte[] szyfrogram, bajt[] klucz) {
        bajt[] plain = nowy bajt[16];
        SMS4 sm4 = nowy SMS4();
        sm4.sms4 (tekst szyfrowy, 16, klucz, prosty, DESZYFROWANY);

        powrót gładki;
    }
Nie będę tu wprowadzał tylko 32-bitowego szyfrowania tekstu jawnego, które jest bardzo podobne do metody używania samego 16-bitowego tekstu jawnego.


Podstawowy algorytm szyfrowania i deszyfrowania bez ograniczania długości tekstu jawnego opiera się na tej zasadzie szyfrowania i deszyfrowania tylko 16 bitów. Dla tekstu jawnego większego niż 16 bitów stosuje się tutaj szyfrowanie pakietów. Jeśli napotkasz tekst jawny, na przykład 30 bitów, którego nie da się podzielić przez 16, jednym ze sposobów na wypełnienie go jest podkreślenie go do poziomu podzielności przez 16. Zasadniczo tylko najmniejszą liczbę można podzielić przez 16, oczywiście, jeśli jesteś zadowolony, nie ma znaczenia, czy ją powiększysz, bo to symbol zamykający.

Szyfrowanie pakietów polega na jednokrotnym zaszyfrowaniu każdego 16-bitowego tekstu jawnego, a następnie ponownym złożeniu zaszyfrowanego 16-bitowego tekstu zaszyfrowanego w nowy szyfrogram. W trakcie deszyfrowania jest on również dzielony na pojedynczy 16-bitowy fragment, a następnie kilka z tych odszyfrowanych tekstów jawnych jest ponownie składanych w nowy tekst jawny.



Demonstracja użycia:



Klucz
        bajt[] key = { 0x01, 0x23, 0x45, 0x67, (bajt) 0x89, (bajt) 0xab,
                (bajt) 0xcd, (bajt) 0xef, (bajt) 0xfe, (bajt) 0xdc,
                (bajt) 0xba, (bajt) 0x98, 0x76, 0x54, 0x32, 0x10 };

        String newString = Kodowanie, hello!; Tekst jawny
        
        bajt[] enOut = SMS4.encodeSMS4(newString, key);
        if (enOut == null) {
            wrócić;
        }
        
        System.out.println(wynik szyfrowania:);
        printBit(enOut);

        bajt[] deOut = SMS4.decodeSMS4(enOut, klucz);
        System.out.println(
wynik deszyfrowania (bajt zwrotny[]) :);
        printBit(deOut);

        String deOutStr = SMS4.decodeSMS4toString(enOut, key);
        System.out.println(
Odszyfruj wynik (zwróć String):
+ deOutStr);
 Ziemianin| Opublikowano 08.12.2015 22:25:41 |
Xiao Zhazha Opublikowano 2015-12-8 22:19
Wprowadzenie do SMS4:

Ten algorytm jest algorytmem grupowania. Algorytm ma długość pakietu 128 bitów i długość klucza 128 bitów, co daje 16 bajtów. ...

Kopiujesz twarz wewnątrz? Uruchamiałem ten algorytm na komputerze kilka razy, ale wciąż nie znam C# w debugowaniu Java, mogę nie znać każdego jego kroku w szczegółach i nie opanowałem jeszcze zasady jego pracy. Java, wiesz, jak debugować każdą jej zmienną?
Opublikowano 08.12.2015 22:40:48 |

Powinno to polegać na ustawieniu punktu przerwania, myeclipse breakpoint, F5 i F6 to debugowanie jednostopniowe, F5 to krok w, czyli wpisanie kodu linii do wykonania, F6 to krok over, czyli wykonanie kodu linii, przeskok do następnej linii
 Ziemianin| Opublikowano 08.12.2015 23:07:37 |
Opublikowano 8 grudnia 2015 22:40
Powinno to polegać na ustawieniu punktu przerwania, myeclipse breakpoint F5 i F6 to oba debugowanie jednostopniowe, F5 to krok do, czyli wpisanie kodu tej linii do wykonania ...

Na pewno wiem, ale nie znam jego konkretnego procesu i nie wiem, kiedy i gdzie przejdę do jakiego etapu specyfikacji. Byłoby miło, gdybyś to zrozumiał
Zrzeczenie się:
Całe oprogramowanie, materiały programistyczne lub artykuły publikowane przez Code Farmer Network służą wyłącznie celom edukacyjnym i badawczym; Powyższe treści nie mogą być wykorzystywane do celów komercyjnych ani nielegalnych, w przeciwnym razie użytkownicy ponoszą wszelkie konsekwencje. Informacje na tej stronie pochodzą z Internetu, a spory dotyczące praw autorskich nie mają z nią nic wspólnego. Musisz całkowicie usunąć powyższą zawartość z komputera w ciągu 24 godzin od pobrania. Jeśli spodoba Ci się program, wspieraj oryginalne oprogramowanie, kup rejestrację i korzystaj z lepszych, autentycznych usług. W przypadku naruszenia praw prosimy o kontakt mailowy.

Mail To:help@itsvse.com