Questo articolo è un articolo speculare di traduzione automatica, clicca qui per saltare all'articolo originale.

Vista: 16332|Risposta: 4

[Algoritmo] Algoritmo SMS4, che è un algoritmo di crittografia a blocchi simmetrica

[Copiato link]
Pubblicato su 08/12/2015 21:49:35 | | |
Questo è un algoritmo di crittografia a blocchi, ma lui usa molte cose, e ora c'è un codice sorgente specifico su Internet, ma questo codice ha comunque un certo valore di ricerca; se anche tu sei interessato, puoi entrare e comunicare e imparare insieme. In realtà, non ha senso darti un codice completo, ma comunque aggiungo l'indirizzo completo al http://www.2cto.com/kf/201501/369374.html
C'è anche una S box al suo interno, molto importante, usata nell'algoritmo DES, quindi il suggerimento del mio collega è di capire chiaramente la S box dell'algoritmo DES, così posso sapere a cosa parla la specifica di questo algoritmo SMS4? La specifica non è allegata.





Precedente:Sembra che questo posto non sia stato aggiornato da molto tempo, e aggiornerò il linguaggio C ogni giorno in futuro.
Prossimo:Linguaggio C, versione completa del video
Pubblicato su 08/12/2015 22:19:05 |

Introduzione a SMS4:

Questo algoritmo è un algoritmo di raggruppamento. L'algoritmo ha una lunghezza del pacchetto di 128 bit e una lunghezza della chiave di 128 bit, cioè 16 byte. Sia l'algoritmo di cifratura che quello di espansione delle chiavi adottano una struttura di iterazione non lineare su 32 round. L'algoritmo di decrittazione ha la stessa struttura dell'algoritmo di cifratura, tranne per il fatto che l'ordine di utilizzo della chiave a round è invertito, e la chiave della ruota di decrittazione è l'ordine inverso della chiave della ruota di crittografia. In tutte le classi base di SMS4, vedrai che le funzioni base di crittografia e decrittazione sono le stesse, ma è necessario un bit di flag di tipo int per determinare se è criptato o decifrato.

Nozioni di base sull'algoritmo di crittografia SMS4:



classe pubblica SMS4 {

    privato static final int ENCRYPT = 1;
    privato statico finale int DECRYPT = 0;
    pubblico statico finale int ROUND = 32;
    blocco privato statico finale, int BLOCK = 16;

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

    private int ByteSub(int A) {
        ritorno (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);
        ritorna 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);
        ritorno 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 = nuovo int[4];
        int[] tmp = nuovo int[4];
        per (int i = 0; Ho < 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]);
        }
        per (r = 0; r < 32; r += 4) {
            mid = x[1] ^ x[2] ^ x[3] ^ rk[r + 0];
            mid = ByteSub(mid);
            x[0] = x[0] ^ L1(medio); x4

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

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

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

        Retromarcia
        per (int j = 0; j < 16; j += 4) {
            Output[j] = (byte) (x[3 - j / 4] >>> 24 & 0xFF);
            Output[j + 1] = (byte) (x[3 - j / 4] >>> 16 & 0xFF);
            Output[j + 2] = (byte) (x[3 - j / 4] >>> 8 & 0xFF);
            Output[j + 3] = (byte) (x[3 - j / 4] & 0xFF);
        }
    }

    private void SMS4KeyExt(byte[] Key, int[] rk, int CryptFlag) {
        int r, mid;
        int[] x = nuovo int[4];
        int[] tmp = nuovo int[4];
        per (int i = 0; Ho < 4; i++) {
            tmp[0] = Tonalità[0 + 4 * i] & 0xFF;
            tmp[1] = Tonalità[1 + 4 * i] & 0xff;
            tmp[2] = Tonalità[2 + 4 * i] & 0xff;
            tmp[3] = Tonalità[3 + 4 * i] & 0xff;
            x= tmp[0] << 24 | TMP[1] << 16 | TMP[2] << 8 | TMP[3];
            x=Key[0+4*i]<<24| Tonalità[1+4*i]<<16| Key[2+4*i]<<8| Tonalità[3+4*i];
        }
        x[0] ^= 0xa3b1bac6;
        x[1] ^= 0x56aa3350;
        x[2] ^= 0x677d9197;
        x[3] ^= 0xb27022dc;
        per (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(mid); rk1=K5

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

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

        Decripta l'ordine della chiave della ruota: rk31, rk30,...,rk0
        if (CryptFlag == DECRYPT) {
            per (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) {
        punto int = 0;
        int[] round_key = nuovo int[ROUND];
        int[] round_key={0};
        SMS4KeyExt (chiave, round_key, CryptFlag);
        Ingresso byte[] = nuovo byte[16];
        byte[] output = nuovo byte[16];

        while (inLen >= BLOCK) {
            input = Arrays.copyOfRange(in, punto, punto + 16);
            output=Arrays.copyOfRange(uscita, punto, punto+16);
            SMS4Crypt (input, output, round_key);
            System.arraycopy(output, 0, out, point, BLOCK);
            inLen -= BLOCCO;
            punto += BLOCCO;
        }

        ritorno 0;
    }
}

Interfaccia esterna confezionata:

Basandosi su questa classe di base, le interfacce principali sono le seguenti:



byte statico privato[] encode16(byte[] plain, byte[] key);
byte statico privato[] decode16(byte[] cifrario, chiave byte[]);
byte statico privato[] encode32(byte[] plain, byte[] key);
byte statico privato[] decode32(byte[] cifrario, byte[] key);
byte statico pubblico[] encodeSMS4(byte[] plain, byte[] key);
byte statico pubblico[] decodeSMS4(cifrario byte[], chiave byte[]);
decodeo statico pubblico StringaSMS4toString(cifrario, chiave byte[]);

encode16(byte[], byte[]) è un'interfaccia per la crittografia di chiavi a 16 bit e chiavi a 16 bit;
Byte statico privato[] Decode16(cifrario byte[] chiave: è un'interfaccia per decifrare testo cifrato a 16 bit e chiave a 16 bit;
Byte statico privato[] encode32(byte[] chiave, chiave byte[]): Questa è un'interfaccia che cifra chiavi a 32 bit e chiavi a 16 bit.
Byte statico privato[] decode32(byte[] cifrato, chiave byte[]): Questa è un'interfaccia per decifrare chiavi cifrate a 32 bit e chiavi a 16 bit.
byte statico pubblico[] encodeSMS4(byte[] plain, byte[] key): Questa è un'interfaccia che cifra il testo in chiaro e le chiavi a 16 bit con un numero illimitato di byte.
byte statico pubblico[] decodeSMS4(byte[] cifrario, chiave byte[]): Questa è un'interfaccia per decifrare il testo cifrato e le chiavi a 16 bit con un numero illimitato di byte.
decodifica statica pubblica StringSMS4toString(byte[] cifratura, chiave byte[]): Questa è un'interfaccia per decifrare byte illimitati di testo cifrato e chiavi a 16 bit.
Codice metodo dell'interfaccia:



byte statico pubblico[] encodeSMS4(Testo in chiaro stringa, chiave byte[]) {
        if (testo in chiaro == null || testo.in chiaro.uguali()) {
            return null;
        }
        per (int i = wordtext.getBytes().length % 16; Ho < 16 anni; i++) {
            testo in chiaro += '';
        }
        
        return SMS4.encodeSMS4(keytext.getBytes(), key);
    }
   
    /**
     * Crittografia SMS4 con lunghezza illimitata del testo in chiaro
     *
     * @param testo in chiaro
     * @param chiave
     * @return
     */
    byte statico pubblico[] encodeSMS4(byte[] testo in chiaro, chiave byte[] {
        byte[] testo cifrato = nuovo byte[wordtext.length];
        
        int k = 0;
        int plainLen = wordtext.length;
        mentre (k + 16 <= plainLen) {
            byte[] cellPlain = nuovo byte[16];
            per (int i = 0; Ho < 16 anni; i++) {
                cellPlain= testo in chiaro[k + i];
            }
            byte[] cellCipher = encode16(cellPlain, key);
            per (int i = 0; i < cellCipher.length; i++) {
                testo cifrato[k + i] = cellCifrario;
            }
            
            k += 16;
        }

        restituire testo cifrato;
    }

    /**
     * Decrittazione SMS4 senza limite di lunghezza del testo in chiaro
     *
     * @param testo cifrato
     * @param chiave
     * @return
     */
    byte statico pubblico[] decodeSMS4(byte[] testo cifrato, chiave byte[] {
        byte[] testo in chiaro = nuovo byte[cifrato.lunghe];
        
        int k = 0;
        int cifraturaLen = cifrato.length;
        mentre (k + 16 <= cipherLen) {
            byte[] cellCipher = nuovo byte[16];
            per (int i = 0; Ho < 16 anni; i++) {
                cellCipher= testo cifrato[k + i];
            }
            byte[] cellPlain = decode16(cellCipher, key);
            per (int i = 0; i < cellPlain.length; i++) {
                testoscritto[k + i] = cellPlain;
            }
            
            k += 16;
        }
        
        restituisci testo in chiaro;
    }

    /**
     * Decrittare per ottenere stringhe di testo in chiaro
     * @param testo cifrato
     * @param chiave
     * @return
     */
    decodeo statico pubblico StringaSMS4toString(byte[] testo cifrato, chiave byte[] {
        byte[] testo in chiaro = nuovo byte[cifrato.lunghe];
        testo in chiaro = decodeSMS4(testo cifrato, chiave);
        return new String(testo in chiaro);
    }

    /**
     * Solo il testo in chiaro a 16 bit è criptato
     *
     * @param testo in chiaro
     * @param chiave
     * @return
     */
    Byte statico privato[] encode16(byte[] chiave, chiave byte[]
        byte[] cifrario = nuovo byte[16];
        SMS4 sm4 = nuovo SMS4();
        sm4.sms4(testo in chiaro, 16, chiave, cifrario, CRITTO);

        return cifrario;
    }

    /**
     * Solo il testo cifrato a 16 bit viene decifrato
     *
     * @param testo in chiaro
     * @param chiave
     * @return
     */
    Byte statico privato[] decode16(byte[] testo cifrato, chiave byte[] {
        byte[] plain = nuovo byte[16];
        SMS4 sm4 = nuovo SMS4();
        sm4.sms4(testo cifrato, 16, chiave, chiave, DECRITTA);

        ritorno pianeggiante;
    }
Non introducerò qui solo la crittografia del testo in chiaro a 32 bit, che è molto simile al metodo del testo in chiaro a solo 16 bit.


L'algoritmo di base per la crittografia e la decrittografia senza limitare la lunghezza del testo in chiaro si basa su questa base di crittografia e decrittografia di soli 16 bit. Per il testo in chiaro superiore a 16 bit, qui si utilizza la crittografia dei pacchetti. Se incontri testo in chiaro come 30 bit che non può essere divisibile per 16, un modo per riempirlo è compensarlo fino a renderlo divisibile per 16. In linea di principio, solo il numero più piccolo può essere diviso per 16, ovviamente, se sei soddisfatto, non importa se lo ingrandisci, perché è il simbolo di chiusura.

La crittografia dei pacchetti consiste nel cifrare ogni testo in chiaro a 16 bit una sola volta, per poi riassemblare il testo cifrato a 16 bit in un nuovo testo cifrato. Nel processo di decrittazione, viene anche suddiviso in un unico pezzo a 16 bit, e poi diversi di questi testi in chiaro decriptati vengono riassemblati in nuovo testo in chiaro.



Dimostrazione di utilizzo:



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

        Stringa nuovaStringa = Programmazione, ciao!; Testo semplice
        
        byte[] enOut = SMS4.encodeSMS4(newString, key);
        if (enOut == null) {
            ritorno;
        }
        
        System.out.println(risultato crittografia:);
        printBit(enOut);

        byte[] deOut = SMS4.decodeSMS4(enOut, chiave);
        System.out.println(
risultato di decrittazione (return byte[]) :);
        printBit(deOut);

        Stringa deOutStr = SMS4.decodeSMS4toString(enOut, chiave);
        System.out.println(
Decripta il risultato (return String):
+ deOutStr);
 Padrone di casa| Pubblicato su 08/12/2015 22:25:41 |
Xiao Zhazha Pubblicato il 8-12-2015 22:19
Introduzione a SMS4:

Questo algoritmo è un algoritmo di raggruppamento. L'algoritmo ha una lunghezza del pacchetto di 128 bit e una lunghezza della chiave di 128 bit, cioè 16 byte. ...

Stai copiando il volto dentro? Ho eseguito questo algoritmo al computer diverse volte, ma non conosco ancora bene C# nel debug Java, e potrei non conoscere ogni suo passaggio nei dettagli, e non ho ancora capito il principio dei suoi dettagli di lavoro. Java, sai come debugare ogni variabile?
Pubblicato su 08/12/2015 22:40:48 |

Dovrebbe essere per impostare il punto di interruzione, la chiave Myeclipse breakpoint F5 e la chiave F6 sono il debug a passo singolo, F5 è passo in ingresso, cioè inserisci il codice linea da eseguire, F6 è passo sopra, cioè eseguire il codice di linea, saltare alla linea successiva
 Padrone di casa| Pubblicato su 08/12/2015 23:07:37 |
Pubblicato il 8-12-2015 alle 22:40
Dovrebbe essere per impostare il punto di interruzione, la chiave Myeclipse breakpoint F5 e la chiave F6 sono entrambe un debug a passo singolo, F5 è passo in ingresso, cioè inserisci il codice di questa riga per eseguire ...

Lo so sicuramente, ma non conosco il suo processo specifico, e non so quando e dove arriverò a quale fase della specifica. Sarebbe bello se capissi
Disconoscimento:
Tutto il software, i materiali di programmazione o gli articoli pubblicati dalla Code Farmer Network sono destinati esclusivamente all'apprendimento e alla ricerca; I contenuti sopra elencati non devono essere utilizzati per scopi commerciali o illegali, altrimenti gli utenti dovranno sostenere tutte le conseguenze. Le informazioni su questo sito provengono da Internet, e le controversie sul copyright non hanno nulla a che fare con questo sito. Devi eliminare completamente i contenuti sopra elencati dal tuo computer entro 24 ore dal download. Se ti piace il programma, ti preghiamo di supportare software autentico, acquistare la registrazione e ottenere servizi autentici migliori. In caso di violazione, vi preghiamo di contattarci via email.

Mail To:help@itsvse.com