Acest articol este un articol oglindă al traducerii automate, vă rugăm să faceți clic aici pentru a sări la articolul original.

Vedere: 16332|Răspunde: 4

[Algoritm] Algoritmul SMS4, care este un algoritm simetric de criptografie pe blocuri

[Copiază linkul]
Postat pe 08.12.2015 21:49:35 | | |
Acesta este un algoritm de criptografie pe blocuri, dar folosește multe lucruri, iar acum există un cod sursă specific pe Internet, dar acest cod are totuși o anumită valoare de cercetare; dacă ești interesat și de asta, puteți intra și comunica și învăța împreună. De fapt, nu are sens să-ți dau un cod complet, dar tot atașez adresa completă a codului la http://www.2cto.com/kf/201501/369374.html
Există și o cutie S în ea, care este foarte importantă, folosită în algoritmul DES, așa că sugestia colegului meu este să înțeleg clar cutia S a algoritmului DES, ca să pot ști la ce se referă specificația acestui algoritm SMS4? Specificația nu este atașată.





Precedent:Se pare că acest loc nu a fost actualizat de mult timp și voi actualiza limbajul C în fiecare zi de acum înainte.
Următor:Limbajul C, versiunea completă video
Postat pe 08.12.2015 22:19:05 |

Introducere în SMS4:

Acest algoritm este un algoritm de grupare. Algoritmul are o lungime a pachetului de 128 de biți și o lungime a cheii de 128 biți, adică 16 octeți. Atât algoritmul de criptare, cât și algoritmul de extindere a cheilor adoptă o structură de iterație neliniară de 32 de runde. Algoritmul de decriptare are aceeași structură ca algoritmul de criptare, cu excepția faptului că ordinea de utilizare a cheii rotunde este inversată, iar cheia roții de decriptare este ordinea inversă a cheii roții de criptare. În toate clasele de bază ale SMS4, veți vedea că funcțiile de bază ale criptării și decriptării sunt aceleași, dar este necesar un bit de tip int pentru a determina dacă este criptat sau decriptat.

Elemente de bază ale algoritmului de criptare SMS4:



clasa publică SMS4 {

    privat static final int ENCRYPT = 1;
    privat static final int DECRYPT = 0;
    public static final int ROUND = 32;
    bloc intern static privat final int BLOCK = 16;

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

    private int ByteSub(int A) {
        retur (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);
        returnează 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 = nou int[4];
        int[] tmp = nou int[4];
        pentru (int i = 0; Am < 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]);
        }
        pentru (r = 0; r < 32; r += 4) {
            mid = x[1] ^ x[2] ^ x[3] ^ rk[r + 0];
            mid = ByteSub(mid);
            x[0] = x[0] ^ L1(mijloc); x4

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

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

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

        Revers
        pentru (int j = 0; J < 16; j += 4) {
            Output[j] = (octet) (x[3 - j / 4] >>> 24 & 0xFF);
            Ieșire[j + 1] = (octet) (x[3 - j / 4] >>> 16 & 0xFF);
            Output[j + 2] = (octet) (x[3 - j / 4] >>> 8 & 0xFF);
            Ieșire[j + 3] = (octet) (x[3 - j / 4] & 0xFF);
        }
    }

    private void SMS4KeyExt(byte[] Key, int[] rk, int CryptFlag) {
        int r, mid;
        int[] x = nou int[4];
        int[] tmp = nou int[4];
        pentru (int i = 0; Am < 4; i++) {
            tmp[0] = Tonalitate[0 + 4 * i] & 0xFF;
            tmp[1] = Cheie[1 + 4 * i] & 0xff;
            tmp[2] = Cheie[2 + 4 * i] & 0xff;
            tmp[3] = Cheie[3 + 4 * i] & 0xff;
            x= tmp[0] << 24 | tmp[1] << 16 | tmp[2] << 8 | tmp[3];
            x=Key[0+4*i]<<24| Cheia[1+4*i]<<16| Cheia[2+4*i]<<8| Cheie[3+4*i];
        }
        x[0] ^= 0xa3b1bac6;
        x[1] ^= 0x56aa3350;
        x[2] ^= 0x677d9197;
        x[3] ^= 0xb27022dc;
        pentru (r = 0; r < 32; r += 4) {
            mid = x[1] ^ x[2] ^ x[3] ^ CK[r + 0];
            mid = ByteSub(mid);
            rk[r + 0] = x[0] ^= L2(mid); rk0=K4

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

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

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

        Decriptează ordinea cheii roții: rk31, rk30,...,rk0
        if (CryptFlag == DECRIPTARE) {
            pentru (r = 0; r < 16; r++) {
                mid = rk[r];
                rk[r] = rk[31 - r];
                rk[31 - r] = mid;
            }
        }
    }

    public int sms4(byte[] in, int inLen, byte[] key, byte[] out, int CryptFlag) {
        punct int = 0;
        int[] round_key = noua int[RUNDĂ];
        int[] round_key={0};
        SMS4KeyExt (cheie, round_key, CryptFlag);
        Octet[] intrare = octet nou[16];
        Ieșire octet[] = octet nou[16];

        while (inLen >= BLOCK) {
            input = Arrays.copyOfRange(in, point, point + 16);
            output=Arrays.copyOfRange(ieșire, punct, punct+16);
            SMS4Crypt (intrare, ieșire, round_key);
            System.arraycopy(output, 0, out, point, BLOCK);
            inLen -= BLOCAJ;
            punct += BLOCAJ;
        }

        returnează 0;
    }
}

Interfață externă ambalată:

Pe baza acestei clase de bază, principalele interfețe sunt următoarele:



byte static privat[] encode16(byte[] plain, byte[] key);
octet static privat[] decodificare 16(cifru octet[] cheie);
byte static privat[] encode32(byte[] plain, byte[] key);
octet static privat[] decode32(cifru octet[] cheie);
octet static public[] encodeSMS4(octet[] simplu, octet[] cheie);
octet static public[] decodificare SMS4(cifru, cheie octet[]);
decod static public StringSMS4toString(byte[] cifru, cheia byte[]);

encode16(octet[], octet[]) este o interfață pentru criptare pentru textul clar pe 16 biți și cheile pe 16 biți;
Octet static privat[] decodificare 16(cifru octet[] cheie: este o interfață pentru decriptarea textului cifrat pe 16 biți și a cheii pe 16 biți;
octet static privat[] encode32(byte[] plain, byte[] key): Aceasta este o interfață care criptează textul clar pe 32 de biți și cheile de 16 biți.
Octet static privat[] decode32(octet[] cifru, cheie de octet[]): Aceasta este o interfață pentru decriptarea textului cifrat pe 32 de biți și cheilor pe 16 biți.
byte static public[] encodeSMS4(byte[] plain, byte[] key): Aceasta este o interfață care criptează textul clar și cheile de 16 biți cu un număr nelimitat de octeți.
octet static public[] decodeSMS4(octet[] cifru, cheia octet[]): Aceasta este o interfață pentru decriptarea textului cifrat și a cheilor de 16 biți cu un număr nelimitat de octeți.
decodare publică statică a stringurilorSMS4toString(byte[] cifrare, cheia byte[]): Aceasta este o interfață pentru decriptarea unui număr nelimitat de octeți de text cifrat și chei pe 16 biți.
Cod metodă de interfață:



octet static public[] encodeSMS4(String plaintext, byte[] key) {
        if (text clar == null || text clar.egal()) {
            returnează nul;
        }
        pentru (int i = text.flatGetBytes().length % 16; Am < 16 ani; i++) {
            text clar += '';
        }
        
        return SMS4.encodeSMS4(text.getBytes(), cheie);
    }
   
    /**
     * Criptare SMS4 cu lungime nelimitată a textului clar
     *
     * @param text simplu
     * @param cheie
     * @return
     */
    octet static public[] encodeSMS4(octet[] text clar, cheia octet[] {
        octet[] text cifrat = nou octet[wordtext.length];
        
        int k = 0;
        int plainLen = textul clar.lungime;
        în timp ce (k + 16 <= plainLen) {
            octet[] cellPlain = octet nou[16];
            pentru (int i = 0; Am < 16 ani; i++) {
                cellPlain= text clar[k + i];
            }
            octet[] cellCipher = encode16(cellPlain, cheie);
            pentru (int i = 0; i < cellCipher.length; i++) {
                text cifrat[k + i] = Cifru celulă;
            }
            
            k += 16;
        }

        returnează textul cifrat;
    }

    /**
     * Decriptare SMS4 fără limită de lungime a textului clar
     *
     * @param text cifrat
     * @param cheie
     * @return
     */
    octet static public[] decodeSMS4(octet[] text cifrat, cheia octet[] {
        octet[] text clar = nou octet[cifrat.lungime];
        
        int k = 0;
        int cipherLen = ciphertext.length;
        în timp ce (k + 16 <= cipherLen) {
            octet[] cellCipher = octet nou[16];
            pentru (int i = 0; Am < 16 ani; i++) {
                cellCipher= text cifrat[k + i];
            }
            octet[] cellPlain = decode16(cellCipher, cheie);
            pentru (int i = 0; i < cellPlain.length; i++) {
                text clar[k + i] = cellPlain;
            }
            
            k += 16;
        }
        
        returnează textul clar;
    }

    /**
     * Decriptare pentru a obține șiruri de texte clare
     * @param text cifrat
     * @param cheie
     * @return
     */
    public static String decodeSMS4toString(byte[] codhertext, byte[] key) {
        octet[] text clar = nou octet[cifrat.lungime];
        text clar = decodeSMS4(text cifrat, cheie);
        return new String (text clar);
    }

    /**
     * Doar textul clar pe 16 biți este criptat
     *
     * @param text simplu
     * @param cheie
     * @return
     */
    Octet static privat[] encode16(octet[] text clar, octet[] cheie) {
        octet[] cifr = octet nou[16];
        SMS4 sm4 = noul SMS4();
        sm4.sms4(text clar, 16, cheie, cifru, CRIPTARE);

        return cipher;
    }

    /**
     * Doar textul cifrat pe 16 biți este decriptat
     *
     * @param text simplu
     * @param cheie
     * @return
     */
    Octet static privat[] decode16(octet[] text cifrat, octet[] cheie) {
        byte[] plain = octet nou[16];
        SMS4 sm4 = noul SMS4();
        sm4.sms4(text cifrat, 16, cheie, simplu, DECRIPTARE);

        să returneze pe plan de răspuns;
    }
Nu voi introduce aici doar criptarea textului clar pe 32 de biți, care este foarte asemănătoare cu metoda textului clar doar pe 16 biți.


Algoritmul de bază pentru criptare și decriptare fără a limita lungimea textului clar se bazează pe această bază: criptarea și decriptarea doar a 16 biți. Pentru textul clar mai mare de 16 biți, aici se folosește criptarea pachetelor. Dacă întâlnești text clar ca 30 de biți care nu pot fi divizibili la 16, o modalitate de a-l completa este să-l compensezi până când devine divizibil cu 16. În principiu, doar cel mai mic număr poate fi împărțit la 16, desigur, dacă ești mulțumit, nu contează dacă îl mărești, pentru că este simbolul de închidere.

Criptarea pachetelor înseamnă să criptezi fiecare text clar de 16 biți o singură dată, apoi să reasamblezi textul cifrat de 16 biți într-un nou text cifrat. În procesul de decriptare, acesta este de asemenea împărțit într-o singură bucată de 16 biți, iar apoi mai multe dintre aceste texte clare decriptate sunt reasamblate în text clar nou.



Demonstrație de utilizare:



Cheie
        Octet[] cheia = { 0x01, 0x23, 0x45, 0x67, (octet) 0x89, (octet) 0xab,
                (octet) 0xcd, (octet) 0xef, (octet) 0xfe, (octet) 0xdc,
                (octet) 0xba, (octet) 0x98, 0x76, 0x54, 0x32, 0x10 };

        String newString = Coding, salut!; Text simplu
        
        octet[] enOut = SMS4.encodeSMS4(newString, cheie);
        if (enOut == null) {
            restitui;
        }
        
        System.out.println (rezultat criptare:);
        printBit(enOut);

        octet[] deOut = SMS4.decodeSMS4(enOut, cheie);
        System.out.println(
Rezultat de decriptare (Return Byte[]) :);
        printBit(deOut);

        String deOutStr = SMS4.decodeSMS4toString(enOut, cheie);
        System.out.println(
Decriptează rezultatul (return String):
+ deOutStr);
 Proprietarul| Postat pe 08.12.2015 22:25:41 |
Xiao Zhazha A Postat pe 2015-12-8 22:19
Introducere în SMS4:

Acest algoritm este un algoritm de grupare. Algoritmul are o lungime a pachetului de 128 de biți și o lungime a cheii de 128 biți, adică 16 octeți. ...

Copiezi fața din interior? Am rulat acest algoritm pe calculator de mai multe ori, dar încă nu sunt familiarizat cu C# în depanarea Java și poate nu îi cunosc fiecare pas în detaliu, și încă nu am descifrat principiul detaliilor sale de lucru. Java, știi cum să depanezi fiecare variabilă a acestuia?
Postat pe 08.12.2015 22:40:48 |

Ar trebui să fie pentru a seta punctul de întrerupere, cheia Myeclipse breakpoint, F5 și cheia F6 sunt depanare single-step, F5 este step in, adică introduci codul liniei pentru executare, F6 este step over, adică execută codul liniei, sari la linia următoare
 Proprietarul| Postat pe 08.12.2015 23:07:37 |
Publicat la 2015-12-8, 22:40
Ar trebui să fie pentru a seta punctul de întrerupere, cheia Myeclipse breakpoint F5 și cheia F6 sunt ambele depanare cu un pas simplu, F5 este pas în, adică introduci codul acestei linii pentru a executa ...

Cu siguranță știu, dar nu cunosc procesul lui specific și nu știu când și unde voi ajunge la ce pas din specificație. Ar fi frumos dacă ai înțelege
Disclaimer:
Tot software-ul, materialele de programare sau articolele publicate de Code Farmer Network sunt destinate exclusiv scopurilor de învățare și cercetare; Conținutul de mai sus nu va fi folosit în scopuri comerciale sau ilegale, altfel utilizatorii vor suporta toate consecințele. Informațiile de pe acest site provin de pe Internet, iar disputele privind drepturile de autor nu au legătură cu acest site. Trebuie să ștergi complet conținutul de mai sus de pe calculatorul tău în termen de 24 de ore de la descărcare. Dacă îți place programul, te rugăm să susții software-ul autentic, să cumperi înregistrarea și să primești servicii autentice mai bune. Dacă există vreo încălcare, vă rugăm să ne contactați prin e-mail.

Mail To:help@itsvse.com