Tento článek je zrcadlovým článkem o strojovém překladu, klikněte zde pro přechod na původní článek.

Pohled: 16332|Odpověď: 4

[Algoritmus] Algoritmus SMS4, což je algoritmus symetrické blokové kryptografie

[Kopírovat odkaz]
Zveřejněno 08.12.2015 21:49:35 | | |
Je to algoritmus blokové kryptografie, ale používá spoustu věcí, a teď existuje specifický zdrojový kód na internetu, ale tento kód má stále určitou výzkumnou hodnotu, pokud vás to také zajímá, můžete přijít a společně se učit. Ve skutečnosti nedává smysl dávat vám kompletní kód, ale přesto připojuji plnou adresu kódu k http://www.2cto.com/kf/201501/369374.html
Je tam také S box, což je velmi důležité a používá se v algoritmu DES, takže mi kolega navrhl jasně pochopit S box algoritmu DES, abych věděl, o čem specifikace v tomto algoritmu SMS4 mluví? Specifikace není připojena.





Předchozí:Zdá se, že toto místo nebylo dlouho aktualizováno a v budoucnu budu každý den aktualizovat jazyk C.
Další:C jazyk, plná verze videa
Zveřejněno 08.12.2015 22:19:05 |

Úvod k SMS4:

Tento algoritmus je seskupovací algoritmus. Algoritmus má délku paketu 128 bitů a délku klíče 128 bitů, což je 16 bajtů. Jak šifrovací algoritmus, tak algoritmus rozšiřování klíče používají 32kolovou nelineární iterační strukturu. Dešifrovací algoritmus má stejnou strukturu jako šifrovací algoritmus, s tím rozdílem, že pořadí použití klíče kola je obrácené a klíč dešifrovacího kolečka je v opačném pořadí klíče šifrovacího kolečka. Ve všech základních třídách SMS4 uvidíte, že základní funkce šifrování a dešifrování jsou stejné, ale je potřeba bit int-typu pro určení, zda je šifrován nebo dešifrován.

Základy šifrovacího algoritmu SMS4:



veřejná třída SMS4 {

    soukromý statický finální int ENCRYPT = 1;
    soukromý statický finální int DECRYPT = 0;
    veřejné statické finále int KOLO = 32;
    soukromý statický finální int BLOCK = 16;

    soukromý 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, (byte) 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 };

    soukromý 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) {
        vrátit 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);
    }

    private 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];
        pro (int i = 0; Jsem < 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]);
        }
        pro (r = 0; r < 32; r += 4) {
            střed = x[1] ^ x[2] ^ x[3] ^ rk[r + 0];
            mid = ByteSub(mid);
            x[0] = x[0] ^ L1(střední); x4

            střed = x[2] ^ x[3] ^ x[0] ^ rk[r + 1];
            mid = ByteSub(mid);
            x[1] = x[1] ^ L1(střední); x5

            střed = x[3] ^ x[0] ^ x[1] ^ rk[r + 2];
            mid = ByteSub(mid);
            x[2] = x[2] ^ L1(střední); x6

            střed = x[0] ^ x[1] ^ x[2] ^ rk[r + 3];
            mid = ByteSub(mid);
            x[3] = x[3] ^ L1(střední); x7
        }

        Reverz
        pro (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];
        pro (int i = 0; Jsem < 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] = Key[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| Key[3+4*i];
        }
        x[0] ^= 0xa3b1bac6;
        x[1] ^= 0x56aa3350;
        x[2] ^= 0x677d9197;
        x[3] ^= 0xb27022dc;
        pro (r = 0; r < 32; r += 4) {
            střed = x[1] ^ x[2] ^ x[3] ^ CK[r + 0];
            mid = ByteSub(mid);
            rk[r + 0] = x[0] ^= L2(střední); rk0=K4

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

            střed = x[3] ^ x[0] ^ x[1] ^ CK[r + 2];
            mid = ByteSub(mid);
            rk[r + 2] = x[2] ^= L2(střední); rk2=K6

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

        Dešifrujte pořadí klíče kolečka: rk31, rk30,...,rk0
        if (CryptFlag == DECRYPT) {
            pro (r = 0; r < 16; r++) {
                střed = rk[r];
                rk[r] = rk[31 - r];
                rk[31 - R] = střed;
            }
        }
    }

    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);
        bajtem[] vstupem = nový bajt[16];
        byte[] output = nový bajt[16];

        while (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í rozhraní:

Na základě této základní třídy jsou hlavní rozhraní následující:



soukromý statický bajt[] encode16(byte[] plain, bajt[] klíč);
soukromý statický bajt[] decode16(byte[] šifra, bajt[] klíč);
soukromý statický bajt[] encode32(byte[] prostý, bajt[] klíč);
soukromý statický bajt[] decode32(byte[] šifra, bajt[] klíč);
veřejný statický bajt[] enkódovat SMS4(bajt[] prostý, bajt[] klíč);
veřejný statický bajt[] dekódovat SMS4(bajt[] šifru, bajt[] klíč);
veřejný statický řetězec dekódovat SMS4toString(byte[] šifra, bajt[] klíč);

encode16(byte[], byte[]) je rozhraní pro šifrování 16bitových otevřených a 16bitových klíčů;
soukromý statický bajt[] decode16(byte[] šifra, bajt[] klíč): je rozhraní pro dešifrování 16bitového šifrovaného textu a 16bitového klíče;
soukromý statický bajt[] encode32(byte[] prostý, bajt[] klíč): Toto je rozhraní, které šifruje 32bitový otevřený text a 16bitové klíče.
soukromý statický bajt[] decode32(byte[] šifra, bajt[] klíč): Toto je rozhraní pro dešifrování 32bitového šifrovaného textu a 16bitových klíčů.
veřejný statický bajt[] encodeSMS4(byte[] plain, bajt[] klíč): Toto je rozhraní, které šifruje otevřený text a 16bitové klíče s neomezeným počtem bajtů.
public static byte[] decodeSMS4(byte[] cipher, byte[] key): Toto je rozhraní pro dešifrování šifrovaného textu a 16bitových klíčů s neomezeným počtem bajtů.
public static String dekódovat SMS4toString(byte[] šifra, bajt[] klíč): Toto je rozhraní pro dešifrování neomezených bajtů šifrovaného textu a 16bitových klíčů.
Kód metody rozhraní:



public static byte[] encodeSMS4(String plaintext, byte[] key) {
        if (plaintext == null || plaintext.equals()) {
            return null;
        }
        for (int i = plaintext.getBytes().length % 16; Je mi < 16; i++) {
            otevřený text += '';
        }
        
        return SMS4.encodeSMS4(plaintext.getBytes(), klíč);
    }
   
    /**
     * Šifrování SMS4 s neomezenou délkou otevřeného textu
     *
     * @param otevřený text
     * @param klíč
     * @return
     */
    veřejný statický bajt[] enkódovat SMS4(bajt[] otevřený text, bajt[] klíč) {
        bajt[] šifrovaný text = nový bajt[plaintext.length];
        
        int k = 0;
        int plainLen = otevřený text.délka;
        zatímco (k + 16 <= plainLen) {
            byte[] cellPlain = nový byte[16];
            pro (int i = 0; Je mi < 16; i++) {
                cellPlain= otevřený text[k + i];
            }
            byte[] cellCipher = encode16(cellPlain, key);
            pro (int i = 0; i < cellCipher.length; i++) {
                šifrovaný text[k + i] = cellCipher;
            }
            
            k += 16;
        }

        vrátit šifrovaný text;
    }

    /**
     * Dešifrování SMS4 bez omezení délky otevřeného textu
     *
     * @param šifrovaný text
     * @param klíč
     * @return
     */
    veřejný statický bajt[] dekódovat SMS4(bajt[] šifrovaný text, bajt[] klíč) {
        byte[] otevřený text = nový bajt[ciphertext.length];
        
        int k = 0;
        int cipherLen = šifrový text.length;
        zatímco (k + 16 <= cipherLen) {
            byte[] cellCipher = nový bajt[16];
            pro (int i = 0; Je mi < 16; i++) {
                cellCipher= šifrovaný text[k + i];
            }
            byte[] cellPlain = decode16(cellCipher, key);
            pro (int i = 0; i < buňkaPlain.délka; i++) {
                otevřený text[k + i] = buňka Plain;
            }
            
            k += 16;
        }
        
        vrátit otevřený text;
    }

    /**
     * Dešifrovat pro získání řetězců otevřeného textu
     * @param šifrovaný text
     * @param klíč
     * @return
     */
    public static String dekódovat SMS4toString(byte[] šifrovaný text, bajt[] klíč) {
        byte[] otevřený text = nový bajt[ciphertext.length];
        otevřený text = dekódovat SMS4(šifrovaný text, klíč);
        vrátit nový řetězec (otevřený text);
    }

    /**
     * Pouze 16bitový otevřený text je zašifrovaný
     *
     * @param otevřený text
     * @param klíč
     * @return
     */
    Soukromý statický bajt[] encode16(byte[] otevřený text, bajt[] klíč) {
        bajt[] šifra = nový bajt[16];
        SMS4 sm4 = nový SMS4();
        sm4.sms4(otevřený text, 16, klíč, šifra, ENCRYPT);

        return šifru;
    }

    /**
     * Dešifrován je pouze 16bitový šifrovaný text
     *
     * @param otevřený text
     * @param klíč
     * @return
     */
    Soukromý statický bajt[] decode16(byte[] šifrovaný text, bajt[] klíč) {
        bajt[] plain = nový byte[16];
        SMS4 sm4 = nový SMS4();
        sm4.sms4 (šifrovaný text, 16, klíč, čistý, DECRYPT);

        Return plain;
    }
Nebudu zde představovat pouze 32bitové šifrování otevřeného textu, které je velmi podobné metodě pouze 16bitového otevřeného textu.


Základní algoritmus pro šifrování a dešifrování bez omezení délky otevřeného textu je založen na tomto základu šifrování a dešifrování pouze 16 bitů. Pro otevřený text větší než 16 bitů se zde používá paketové šifrování. Pokud narazíte na otevřený text jako 30 bitů, který nelze dělit 16, jedním ze způsobů, jak ho zaplnit, je dělit ho tak, aby byl dělitelný 16. V zásadě lze dělit jen nejmenší číslo šestnácti, samozřejmě, pokud jste spokojení, nezáleží na tom, jestli ho zvětšíte, protože je to závěrečný symbol.

Paketové šifrování spočívá v jednom zašifrování každého 16bitového otevřeného textu a následném složení zašifrovaného 16bitového šifrovaného textu do nového šifrovaného textu. Při dešifrování je také rozdělen na jeden 16bitový kus a poté je několik těchto dešifrovaných otevřených textů znovu sestaveno do nového otevřeného textu.



Demonstrace použití:



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

        String newString = Kódování, ahoj!; Prostý text
        
        byte[] enOut = SMS4.encodeSMS4(newString, key);
        if (enOut == null) {
            vrátit;
        }
        
        System.out.println(výsledek šifrování:);
        printBit(enOut);

        byte[] deOut = SMS4.decodeSMS4(enOut, klíč);
        System.out.println(
výsledek dešifrování (return byte[]) :);
        printBit(deOut);

        String deOutStr = SMS4.decodeSMS4toString(enOut, key);
        System.out.println(
Dešifrujte výsledek (vrátit řetězec):
+ deOutStr);
 Pronajímatel| Zveřejněno 08.12.2015 22:25:41 |
Xiao Zhazha Zveřejněno 8. 12. 2015 22:19
Úvod k SMS4:

Tento algoritmus je seskupovací algoritmus. Algoritmus má délku paketu 128 bitů a délku klíče 128 bitů, což je 16 bajtů. ...

Kopíruješ obličej uvnitř? Tento algoritmus jsem na počítači spustil několikrát, ale stále nejsem obeznámen s C# v ladění v Javě, možná neznám každý jeho krok do detailu a ještě jsem nepochopil princip jeho pracovních detailů. Java, víš, jak ladit všechny proměnné?
Zveřejněno 08.12.2015 22:40:48 |

Mělo by to být pro nastavení breakpointu, myeclipse breakpoint F5 a klávesy F6 jsou jednokrokové ladění, F5 je krok do, tedy zadání řádkového kódu pro vykonání, F6 je krok over, tedy spuštění řádkového kódu, skok na další řádek
 Pronajímatel| Zveřejněno 08.12.2015 23:07:37 |
Publikováno 8. 12. 2015 v 22:40
Mělo by to být pro nastavení breakpointu, myeclipse breakpoint F5 a F6 jsou oba jednokrokové ladění, F5 je krok do, tedy zadání kódu tohoto řádku pro provedení ...

Určitě to vím, ale neznám jeho konkrétní postup a nevím, kdy a kde se dostanu k jakému kroku ve specifikaci. Bylo by hezké, kdybys to pochopil
Zřeknutí se:
Veškerý software, programovací materiály nebo články publikované organizací Code Farmer Network slouží pouze k učení a výzkumu; Výše uvedený obsah nesmí být používán pro komerční ani nelegální účely, jinak nesou všechny důsledky uživatelé. Informace na tomto webu pocházejí z internetu a spory o autorská práva s tímto webem nesouvisí. Musíte výše uvedený obsah ze svého počítače zcela smazat do 24 hodin od stažení. Pokud se vám program líbí, podporujte prosím originální software, kupte si registraci a získejte lepší skutečné služby. Pokud dojde k jakémukoli porušení, kontaktujte nás prosím e-mailem.

Mail To:help@itsvse.com