Tento článok je zrkadlovým článkom o strojovom preklade, kliknite sem pre prechod na pôvodný článok.

Pohľad: 16332|Odpoveď: 4

[Algoritmus] Algoritmus SMS4, ktorý je algoritmus symetrickej blokovej kryptografie

[Kopírovať odkaz]
Zverejnené 8. 12. 2015 21:49:35 | | |
Je to algoritmus blokovej kryptografie, ale používa veľa vecí, a teraz existuje špecifický zdrojový kód na internete, ale tento kód má stále určitú výskumnú hodnotu, ak vás to tiež zaujíma, môžete prísť a komunikovať a učiť sa spolu. V skutočnosti nedáva zmysel dávať vám kompletný kód, ale aj tak pripájam úplnú adresu kódu k http://www.2cto.com/kf/201501/369374.html
Je tam tiež S box, čo je veľmi dôležité a používa sa v algoritme DES, takže môj kolega mi navrhol jasne pochopiť S box v algoritme DES, aby som vedel, o čom hovorí špecifikácia v tomto algoritme SMS4. Špecifikácia nie je priložená.





Predchádzajúci:Zdá sa, že toto miesto už dlho nebolo aktualizované a v budúcnosti budem každý deň aktualizovať jazyk C.
Budúci:C jazyk, plná verzia videa
Zverejnené 8. 12. 2015 22:19:05 |

Úvod k SMS4:

Tento algoritmus je zoskupovací algoritmus. Algoritmus má dĺžku paketu 128 bitov a dĺžku kľúča 128 bitov, čo je 16 bajtov. Šifrovací algoritmus aj algoritmus rozširovania kľúčov používajú 32-kolovú nelineárnu iteráciu. Dešifrovací algoritmus má rovnakú štruktúru ako šifrovací algoritmus, s tým rozdielom, že poradie použitia kľúča kola je obrátené a kľúč koliesa na dešifrovanie je v opačnom poradí kľúča na šifrovacie koliesko. Vo všetkých základných triedach SMS4 uvidíte, že základné funkcie šifrovania a dešifrovania sú rovnaké, ale na určenie, či ide o šifrovanie alebo dešifrovanie, je potrebný bit int-typu flagu.

Základy šifrovacieho algoritmu SMS4:



verejná trieda SMS4 {

    súkromný statický konečný int ENCRYPT = 1;
    súkromný statický finálny int DECRYPT = 0;
    verejné statické finále int KOLO = 32;
    súkromný statický finálny int BLOCK = 16;

    súkromný bajt[] 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 };

    súkromný 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 };

    súkromný int Rotl(int x, int y) {
        vrátiť 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);
    }

    súkromný 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 = nový int[4];
        int[] tmp = nový int[4];
        pre (int i = 0; Mám < 4; i++) {
            tmp[0] = Vstup[0 + 4 * i] & 0xff;
            tmp[1] = Vstup[1 + 4 * i] & 0xff;
            tmp[2] = Vstup[2 + 4 * i] & 0xff;
            tmp[3] = Vstup[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| vstup[3+4*i]);
        }
        pre (r = 0; r < 32; r += 4) {
            stred = x[1] ^ x[2] ^ x[3] ^ rk[r + 0];
            mid = ByteSub(mid);
            x[0] = x[0] ^ L1(stred); x4

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

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

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

        Reverz
        pre (int j = 0; j < 16; j += 4) {
            Výstup[j] = (bajt) (x[3 - j / 4] >>> 24 & 0xFF);
            Výstup[j + 1] = (bajt) (x[3 - j / 4] >>> 16 & 0xFF);
            Výstup[j + 2] = (bajt) (x[3 - j / 4] >>> 8 & 0xFF);
            Výstup[j + 3] = (bajt) (x[3 - j / 4] & 0xFF);
        }
    }

    private void SMS4KeyExt(byte[] Key, int[] rk, int CryptFlag) {
        int r, mid;
        int[] x = nový int[4];
        int[] tmp = nový int[4];
        pre (int i = 0; Mám < 4; i++) {
            tmp[0] = Key[0 + 4 * i] & 0xFF;
            tmp[1] = Key[1 + 4 * i] & 0xff;
            tmp[2] = Key[2 + 4 * i] & 0xff;
            tmp[3] = Kľúč[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| Kľúč[3+4*i];
        }
        x[0] ^= 0xa3b1bac6;
        x[1] ^= 0x56aa3350;
        x[2] ^= 0x677d9197;
        x[3] ^= 0xb27022dc;
        pre (r = 0; r < 32; r += 4) {
            stred = x[1] ^ x[2] ^ x[3] ^ CK[r + 0];
            mid = ByteSub(mid);
            rk[r + 0] = x[0] ^= L2(stred); rk0=K4

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

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

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

        Dešifrovanie poradia kľúča kolieskom: rk31, rk30,...,rk0
        ak (CryptFlag == DECRYPT) {
            pre (r = 0; r < 16; r++) {
                stred = rk[r];
                rk[r] = rk[31 - r];
                rk[31 - R] = stred;
            }
        }
    }

    public int sms4(byte[] in, int inLen, byte[] key, byte[] out, int CryptFlag) {
        int bod = 0;
        int[] round_key = nový int[ROUND];
        int[] round_key={0};
        SMS4KeyExt(key, round_key, CryptFlag);
        bajt[] vstup = nový bajt[16];
        bajt[] output = nový bajt[16];

        zatiaľ čo (inLen >= BLOCK) {
            input = Arrays.copyOfRange(in, point, point + 16);
            output=Arrays.copyOfRange(out, point, point+16);
            SMS4Crypt (vstup, výstup, round_key);
            System.arraycopy(output, 0, out, point, BLOCK);
            inLen -= BLOK;
            bod += BLOK;
        }

        return 0;
    }
}

Balené externé rozhranie:

Na základe tejto základnej triedy sú hlavné rozhrania nasledovné:



súkromný statický bajt[] encode16(byte[] plain, bajt[] kľúč);
súkromný statický bajt[] decode16(byte[] šifra, bajt[] kľúč);
súkromný statický bajt[] encode32(byte[] plain, bajt[] kľúč);
súkromný statický bajt[] decode32(bajt[] šifra, bajt[] kľúč);
verejný statický bajt[] enkódovať SMS4(bajt[] obyčajný, bajt[] kľúč);
verejný statický bajt[] dekódovať SMS4(bajt[] šifra, bajt[] kľúč);
public static String dekódovať SMS4toString(byte[] šifra, bajt[] kľúč);

encode16(byte[], byte[]) je rozhranie na šifrovanie pre 16-bitový otvorený text a 16-bitové kľúče;
súkromný statický bajt[] decode16(byte[] šifra, bajt[] kľúč): je rozhranie na dešifrovanie 16-bitového šifrovaného textu a 16-bitového kľúča;
súkromný statický bajt[] encode32(byte[] plain, bajt[] kľúč): Toto je rozhranie, ktoré šifruje 32-bitový otvorený text a 16-bitové kľúče.
súkromný statický bajt[] decode32(byte[] šifra, bajt[] kľúč): Toto je rozhranie na dešifrovanie 32-bitového šifrovaného textu a 16-bitových kľúčov.
public static byte[] encodeSMS4(byte[] plain, byte[] key): Toto je rozhranie, ktoré šifruje otvorený text a 16-bitové kľúče s neobmedzeným počtom bajtov.
public static byte[] decodeSMS4(byte[] cipher, byte[] key): Toto je rozhranie na dešifrovanie šifrovaného textu a 16-bitových kľúčov s neobmedzeným počtom bajtov.
public static String decodeSMS4toString(byte[] cipher, byte[] key): Toto je rozhranie na dešifrovanie neobmedzeného počtu bajtov šifrovaného textu a 16-bitových kľúčov.
Kód metódy rozhrania:



public static byte[] encodeSMS4(String plaintext, byte[] key) {
        if (plaintext == null || plaintext.equals()) {
            return null;
        }
        for (int i = plaintext.getBytes().length % 16; Mám < 16; i++) {
            otvorený text += '';
        }
        
        return SMS4.encodeSMS4(plaintext.getBytes(), kľúč);
    }
   
    /**
     * Šifrovanie SMS4 s neobmedzenou dĺžkou otvoreného textu
     *
     * @param otvorený text
     * @param kľúč
     * @return
     */
    verejný statický bajt[] enkódovať SMS4(byte[] otvorený text, bajt[] kľúč) {
        bajt[] šifrovaný text = nový bajt[plaintext.length];
        
        int k = 0;
        int plainLen = otvorený text.dĺžka;
        zatiaľ čo (k + 16 <= plainLen) {
            bajt[] cellPlain = nový bajt[16];
            pre (int i = 0; Mám < 16; i++) {
                cellPlain= otvorený text[k + i];
            }
            byte[] cellCipher = encode16(cellPlain, key);
            pre (int i = 0; i < cellCipher.length; i++) {
                šifrovaný text[k + i] = cellCipher;
            }
            
            k += 16;
        }

        vrátiť šifrovaný text;
    }

    /**
     * Dešifrovanie SMS4 bez obmedzenia dĺžky otvoreného textu
     *
     * @param šifrovaný text
     * @param kľúč
     * @return
     */
    verejný statický bajt[] dekódovať SMS4(bajt[] šifrovaný text, bajt[] kľúč) {
        bajt[] otvorený text = nový bajt[cyfertext.dĺžka];
        
        int k = 0;
        int cipherLen = šifrovaný text.length;
        zatiaľ čo (k + 16 <= cipherLen) {
            byte[] cellCipher = nový bajt[16];
            pre (int i = 0; Mám < 16; i++) {
                cellCipher= šifrovaný text[k + i];
            }
            byte[] cellPlain = decode16(cellCipher, key);
            pre (int i = 0; i < bunkaPlain.dĺžka; i++) {
                otvorený text[k + i] = cellPlain;
            }
            
            k += 16;
        }
        
        vrátiť otvorený text;
    }

    /**
     * Dešifrovanie na získanie reťazcov otvoreného textu
     * @param šifrovaný text
     * @param kľúč
     * @return
     */
    public static String dekódovať SMS4toString(byte[] šifrovaný text, bajt[] kľúč) {
        bajt[] otvorený text = nový bajt[cyfertext.dĺžka];
        otvorený text = dekódovať SMS4(šifrovaný text, kľúč);
        vrátiť nový reťazec (otvorený text);
    }

    /**
     * Iba 16-bitový otvorený text je šifrovaný
     *
     * @param otvorený text
     * @param kľúč
     * @return
     */
    Súkromný statický bajt[] encode16(byte[] otvorený text, bajt[] kľúč) {
        bajt[] šifra = nový bajt[16];
        SMS4 sm4 = nový SMS4();
        sm4.sms4(otvorený text, 16, kľúč, šifra, ENCRYPT);

        return šifra;
    }

    /**
     * Dešifrovaný je iba 16-bitový šifrovaný text
     *
     * @param otvorený text
     * @param kľúč
     * @return
     */
    súkromný statický bajt[] decode16(byte[] šifrovaný text, bajt[] kľúč) {
        bajt[] plain = nový bajt[16];
        SMS4 sm4 = nový SMS4();
        sm4.sms4 (šifrovaný text, 16, kľúč, čistý, DECRYPT);

        vráť hladko;
    }
Nebudem tu predstavovať len 32-bitové šifrovanie otvoreného textu, ktoré je veľmi podobné metóde iba 16-bitového otvoreného textu.


Základný algoritmus šifrovania a dešifrovania bez obmedzenia dĺžky otvoreného textu je založený na tomto princípe šifrovania a dešifrovania iba 16 bitov. Pre otvorený text väčší ako 16 bitov sa tu používa šifrovanie paketov. Ak narazíte na otvorený text ako 30 bitov, ktorý sa nedá deliť 16, spôsob, ako ho zaplniť, je vyplniť ho tak, že bude deliteľný 16. V princípe sa dá deliť len najmenšie číslo 16, samozrejme, ak ste spokojní, nezáleží na tom, či ho zväčšíte, pretože je to záverečný symbol.

Paketové šifrovanie spočíva v jednom zašifrovaní každého 16-bitového otvoreného textu a následnom zložení zašifrovaného 16-bitového šifrovaného textu do nového šifrovaného textu. Pri dešifrovaní sa tiež rozdelí na jeden 16-bitový kus a potom sa niekoľko z týchto dešifrovaných otvorených textov znovu poskladá do nového otvoreného textu.



Demonštrácia používania:



Kľúč
        bajt[] kľúč = { 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 = Kódovanie, ahoj!; Neobyčajný text
        
        byte[] enOut = SMS4.encodeSMS4(newString, key);
        ak (enOut == null) {
            vrátiť;
        }
        
        System.out.println(výsledok šifrovania:);
        printBit(enOut);

        bajt[] deOut = SMS4.dekódovať SMS4(enOut, kľúč);
        System.out.println(
výsledok dešifrovania (return byte[]) :);
        printBit(deOut);

        String deOutStr = SMS4.decodeSMS4toString(enOut, key);
        System.out.println(
Dešifrovať výsledok (vrátiť reťazec):
+ deOutStr);
 Prenajímateľ| Zverejnené 8. 12. 2015 22:25:41 |
Xiao Zhazha Zverejnené 8.12.2015 22:19
Úvod k SMS4:

Tento algoritmus je zoskupovací algoritmus. Algoritmus má dĺžku paketu 128 bitov a dĺžku kľúča 128 bitov, čo je 16 bajtov. ...

Kopíruješ tvár vo vnútri? Tento algoritmus som na počítači spustil niekoľkokrát, ale stále nepoznám C# v ladení v Jave, možno nepoznám každý jeho krok do detailov a ešte som nepochopil princíp jeho pracovných detailov. Java, vieš ladiť každú premennú?
Zverejnené 8. 12. 2015 22:40:48 |

Malo by to byť na nastavenie breakpointu, myeclipse breakpoint F5 a F6 sú jednokrokové ladenie, F5 je krok do, teda zadať riadkový kód na vykonanie, F6 je krok over, teda vykonať riadkový kód, preskočiť na ďalší riadok
 Prenajímateľ| Zverejnené 8. 12. 2015 23:07:37 |
Publikované 8.12.2015 o 22:40
Malo by to byť na nastavenie breakpointu, myeclipse breakpoint F5 a F6 sú oba jednokrokové ladenie, F5 je krok do, teda zadať kód tohto riadku na vykonanie ...

Určite to viem, ale nepoznám jeho konkrétny postup a neviem, kedy a kde sa dostanem k akému kroku v špecifikácii. Bolo by fajn, keby si to pochopil
Vyhlásenie:
Všetok softvér, programovacie materiály alebo články publikované spoločnosťou Code Farmer Network slúžia len na vzdelávacie a výskumné účely; Vyššie uvedený obsah nesmie byť použitý na komerčné alebo nezákonné účely, inak nesú všetky následky používateľmi. Informácie na tejto stránke pochádzajú z internetu a spory o autorské práva s touto stránkou nesúvisia. Musíte úplne vymazať vyššie uvedený obsah zo svojho počítača do 24 hodín od stiahnutia. Ak sa vám program páči, podporte originálny softvér, zakúpte si registráciu a získajte lepšie originálne služby. Ak dôjde k akémukoľvek porušeniu, kontaktujte nás prosím e-mailom.

Mail To:help@itsvse.com