Denna artikel är en spegelartikel om maskinöversättning, klicka här för att hoppa till originalartikeln.

Utsikt: 16332|Svar: 4

[Algoritm] SMS4-algoritmen, som är en symmetrisk blockkryptografialgoritm

[Kopiera länk]
Publicerad på 2015-12-08 21:49:35 | | |
Det här är en blockkryptografialgoritm, men den använder mycket, och nu finns det en specifik källkod på Internet, men denna kod har fortfarande ett visst forskningsvärde, om du också är intresserad av detta kan ni komma in och kommunicera och lära er tillsammans. Faktum är att det inte är meningsfullt att ge dig en komplett kod, men jag bifogar ändå hela kodadressen till http://www.2cto.com/kf/201501/369374.html
Det finns också en S-ruta i den, vilket är mycket viktigt, och som används i DES-algoritmen, så min kollegas förslag till mig är att förstå S-rutan i DES-algoritmen tydligt, så att jag kan veta vad specifikationen i denna SMS4-algoritm syftar på? Specifikationen är inte bifogad.





Föregående:Det verkar som att den här platsen inte har uppdaterats på länge, och jag kommer att uppdatera C-språket varje dag i framtiden.
Nästa:C-språket, fullversion video
Publicerad på 2015-12-08 22:19:05 |

SMS4-introduktion:

Denna algoritm är en grupperingsalgoritm. Algoritmen har en paketlängd på 128 bitar och en nyckelstorlek på 128 bitar, vilket är 16 byte. Både krypteringsalgoritmen och nyckelexpansionsalgoritmen använder en 32-rundors icke-linjär iterationsstruktur. Dekrypteringsalgoritmen har samma struktur som krypteringsalgoritmen, förutom att ordningen för rundnyckelns användning är omvänd, och dekrypteringshjulnyckeln är den omvända ordningen av krypteringshjulnyckeln. I alla basklasser av SMS4 kommer du att se att basfunktionerna kryptering och dekryptering är desamma, men en int-typ flaggbit behövs för att avgöra om den är krypterad eller dekrypterad.

Grundläggande för SMS4-krypteringsalgoritmer:



public class SMS4 {

    privat statisk final int ENCRYPT = 1;
    privat statisk slutint DECRYPT = 0;
    offentlig statisk final INT RUNDA = 32;
    privat statisk slutgiltig int BLOCK = 16;

    privat 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 };

    privat 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 };

    privat int Rotl(int x, int y) {
        returnera x << y | x >>> (32 - y);
    }

    private int ByteSub(int A) {
        återkomma (Sbox [A >>> 24 & 0xFF] & 0xFF) << 24
                | (Sbox[A >>> 16 & 0xFF] & 0xFF) << 16
                | (Sbox [A >>> 8 & 0xFF] & 0xFF) << 8 | (Sbox[A & 0xFF] & 0xFF);
    }

    privat int L1(int B) {
        retur B ^ Rotl(B, 2) ^ Rotl(B, 10) ^ Rotl(B, 18) ^ Rotl(B, 24);
        returnera B^(B<<2|B>>>30)^(B<<10|B>>>22)^(B<<18|B>>>14)^(B<<24|B>>>8);
    }

    privat int L2(int B) {
        retur B ^ Rotl(B, 13) ^ Rotl(B, 23);
        returnera 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 = ny int[4];
        int[] tmp = ny int[4];
        för (int i = 0; Jag < 4; i++) {
            tmp[0] = Input[0 + 4 * i] & 0xff;
            tmp[1] = Inmatning[1 + 4 * i] & 0xff;
            tmp[2] = Input[2 + 4 * i] & 0xff;
            tmp[3] = Ingång[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]);
        }
        för (r = 0; r < 32; r += 4) {
            mid = x[1] ^ x[2] ^ x[3] ^ rk[r + 0];
            mid = ByteSub(mid);
            x[0] = x[0] ^ L1(mitten); x4

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

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

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

        Baksidan
        för (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 = ny int[4];
        int[] tmp = ny int[4];
        för (int i = 0; Jag < 4; i++) {
            tmp[0] = Nyckel[0 + 4 * i] & 0xFF;
            tmp[1] = Nyckel[1 + 4 * i] & 0xff;
            tmp[2] = Nyckel[2 + 4 * i] & 0xff;
            tmp[3] = Nyckel[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;
        för (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(mitt); rk0=K4

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

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

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

        Dekryptera ordningen på hjulnyckeln: rk31, rk30,...,rk0
        om (CryptFlag == DEKRYPTERA) {
            för (r = 0; r < 16; r++) {
                mid = rk[r];
                rk[r] = rk[31 - r];
                rk[31 - r] = mitten;
            }
        }
    }

    public int sms4(byte[] in, int inLen, byte[] key, byte[] out, int CryptFlag) {
        int point = 0;
        int[] round_key = ny int[RUNDA];
        int[] round_key={0};
        SMS4KeyExt(nyckel, round_key, CryptFlag);
        byte[] input = ny byte[16];
        byte[] output = ny byte[16];

        medan (inLen >= BLOCK) {
            input = Arrays.copyOfRange(in, punkt, punkt + 16);
            output=Arrays.copyOfRange(ut, punkt, punkt+16);
            SMS4Crypt (inmatning, utmatning, round_key);
            System.arraycopy (utdata, 0, ut, punkt, BLOCK);
            inLen -= BLOCK;
            punkt += BLOCK;
        }

        returnera 0;
    }
}

Paketerat externt gränssnitt:

Baserat på denna grundläggande klass är huvudgränssnitten följande:



privat statisk byte[] encode16(byte[] plain, byte[] nyckel);
privat statisk byte[] decode16(byte[] chiffer, byte[] nyckel);
privat statisk byte[] encode32(byte[] plain, byte[] nyckel);
privat statisk byte[] decode32(byte[] chiffer, byte[] nyckel);
publik statisk byte[] encodeSMS4(byte[] plain, byte[] nyckel);
publik statisk byte[] dekodningSMS4(byte[] chiffer, byte[] nyckel);
offentlig statisk strängavkodningSMS4toString(byte[] chiffer, byte[]-nyckel);

encode16(byte[], byte[]) är ett gränssnitt för kryptering av 16-bitars klartext och 16-bitars nycklar;
privat statisk byte[] decode16(byte[] chiffer, byte[] nyckel): är ett gränssnitt för att dekryptera 16-bitars chiffertext och 16-bitars nyckel;
privat statisk byte[] encode32(byte[] plain, byte[] key): Detta är ett gränssnitt som krypterar 32-bitars klartext och 16-bitars nycklar.
privat statisk byte[] decode32(byte[] chiffer, byte[] nyckel): Detta är ett gränssnitt för att dekryptera 32-bitars chiffertext och 16-bitars nycklar.
public static byte[] encodeSMS4(byte[] plain, byte[] key): Detta är ett gränssnitt som krypterar klartext och 16-bitars nycklar med ett obegränsat antal byte.
public static byte[] decodeSMS4(byte[] chiffer, byte[] nyckel): Detta är ett gränssnitt för att dekryptera chiffertext och 16-bitars nycklar med ett obegränsat antal byte.
offentlig statisk strängavkodningSMS4toString(byte[] chiffer, byte[] nyckel): Detta är ett gränssnitt för att dekryptera obegränsade byte chiffertext och 16-bitars nycklar.
Gränssnittsmetodkod:



publik statisk byte[] encodeSMS4(Sträng klartext, byte[] nyckel) {
        om (klartext == null || klartext.equals()) {
            återvända null;
        }
        för (int i = klartext.getBytes().length % 16; Jag < 16; i++) {
            klartext += '';
        }
        
        returnera SMS4.encodeSMS4(plaintext.getBytes(), nyckel);
    }
   
    /**
     * SMS4-kryptering med obegränsad klartextlängd
     *
     * @param klartext
     * @param nyckel
     * @return
     */
    publik statisk byte[] encodeSMS4(byte[] klartext, byte[] nyckel) {
        byte[] chiffertext = ny byte[klartext.längd];
        
        int k = 0;
        int plainLen = klartext.längd;
        medan (k + 16 <= plainLen) {
            byte[] cellPlain = ny byte[16];
            för (int i = 0; Jag < 16; i++) {
                cellPlain= klartext[k + i];
            }
            byte[] cellCipher = kod16(cellPlain, nyckel);
            för (int i = 0; i < cellCipher.length; i++) {
                ciphertext[k + i] = cellCipher;
            }
            
            k += 16;
        }

        returnera chiffertext;
    }

    /**
     * SMS4-dekryptering utan begränsning av klartextlängd
     *
     * @param chiffertext
     * @param nyckel
     * @return
     */
    publik statisk byte[] decodeSMS4(byte[] ciphertext, byte[] key) {
        byte[] klartext = ny byte[chiffertext.length];
        
        int k = 0;
        int cipherLen = ciphertext.length;
        medan (k + 16 <= chifferLen) {
            byte[] cellCipher = ny byte[16];
            för (int i = 0; Jag < 16; i++) {
                cellCipher= chiffertext[k + i];
            }
            byte[] cellPlain = decode16(cellCipher, key);
            för (int i = 0; i < cellPlain.length; i++) {
                klartext[k + i] = cellPlain;
            }
            
            k += 16;
        }
        
        returnera klartext;
    }

    /**
     * Dekryptera för att få klartextsträngar
     * @param chiffertext
     * @param nyckel
     * @return
     */
    publik statisk String decodeSMS4toString(byte[] ciphertext, byte[] key) {
        byte[] klartext = ny byte[chiffertext.length];
        klartext = dekoda SMS4 (chiffertext, nyckel);
        returnera ny sträng (klartext);
    }

    /**
     * Endast 16-bitars klartext är krypterad
     *
     * @param klartext
     * @param nyckel
     * @return
     */
    privat statisk byte[] encode16(byte[] klartext, byte[] nyckel) {
        byte[] chiffer = ny byte[16];
        SMS4 sm4 = ny SMS4();
        sm4.sms4 (klartext, 16, nyckel, chiffer, ENCRYPT);

        returnera chiffer;
    }

    /**
     * Endast 16-bitars chiffertext dekrypteras
     *
     * @param klartext
     * @param nyckel
     * @return
     */
    privat statisk byte[] decode16(byte[] ciphertext, byte[] key) {
        byte[] plain = ny byte[16];
        SMS4 sm4 = ny SMS4();
        sm4.sms4 (ciphertext, 16, key, plain, DECRYPT);

        återvänd rakt ut;
    }
Jag kommer inte att införa endast 32-bitars klartextkryptering här, vilket är mycket likt metoden med endast 16-bitars klartext.


Den grundläggande algoritmen för kryptering och dekryptering utan att begränsa klartextens längd baseras på denna grund, där endast 16 bitar krypteras och dekrypteras. För klartext större än 16 bitar används paketkryptering här. Om du stöter på klartext som 30 bitar som inte kan delas med 16, är ett sätt att fylla på det att göra det så långt att det är delbart med 16. I princip kan bara det minsta talet delas med 16, men om du är nöjd spelar det ingen roll om du gör det större, eftersom det är avslutningssymbolen.

Paketkryptering innebär att varje 16-bitars klartext krypteras en gång och sedan sammanställs den krypterade 16-bitars chiffertexten till en ny chiffertext. I dekrypteringsprocessen delas den också upp i en enda 16-bitars del, och sedan återsätts flera av dessa dekrypterade klartexter till ny klartext.



Användningsdemonstration:



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

        String newString = Kodning, hej!; Klartext
        
        byte[] enOut = SMS4.encodeSMS4(newString, key);
        om (enOut == null) {
            återvända;
        }
        
        System.out.println(krypteringsresultat:);
        printBit(enOut);

        byte[] deOut = SMS4.decodeSMS4(enOut, key);
        System.out.println(
dekrypteringsresultat (return byte[]) :);
        printBit(deOut);

        String deOutStr = SMS4.decodeSMS4toString(enOut, key);
        System.out.println(
Dekryptera resultatet (returnera sträng):
+ deOutStr);
 Hyresvärd| Publicerad på 2015-12-08 22:25:41 |
Xiao Zhazha Publicerad den 2015-12-8 22:19
SMS4-introduktion:

Denna algoritm är en grupperingsalgoritm. Algoritmen har en paketlängd på 128 bitar och en nyckelstorlek på 128 bitar, vilket är 16 byte. ...

Kopierar du ansiktet inuti? Jag har kört denna algoritm på datorn flera gånger, men jag är fortfarande inte bekant med C# i Java-felsökning, och jag kanske inte känner till varje steg i detalj, och jag har ännu inte listat ut principen för hans arbetsdetaljer. Java, vet du hur man felsöker varje variabel i den?
Publicerad på 2015-12-08 22:40:48 |

Det ska vara för att ställa in brytpunkten, myeclipse-brytpunkten F5-tangenten och F6-tangenten är enkelstegsfelsökning, F5 är steg-in, det vill säga mata in radkoden för att exekveras, F6 är steg-över, det vill säga köra linjekoden, hoppa till nästa rad
 Hyresvärd| Publicerad på 2015-12-08 23:07:37 |
Publicerad den 2015-12-8 22:40
Det bör vara för att sätta brytpunkten, myeclipsebrytningspunkten F5-tangenten och F6-tangenten är båda enkelstegsfelsökning, F5 är steg in, det vill säga mata in koden för denna rad för att köra ...

Jag vet definitivt, men jag känner inte till hans specifika process, och jag vet inte när och var jag kommer till vilket steg i specifikationen. Det vore trevligt om du förstod
Friskrivning:
All programvara, programmeringsmaterial eller artiklar som publiceras av Code Farmer Network är endast för lärande- och forskningsändamål; Ovanstående innehåll får inte användas för kommersiella eller olagliga ändamål, annars kommer användarna att bära alla konsekvenser. Informationen på denna sida kommer från internet, och upphovsrättstvister har inget med denna sida att göra. Du måste helt radera ovanstående innehåll från din dator inom 24 timmar efter nedladdning. Om du gillar programmet, vänligen stöd äkta programvara, köp registrering och få bättre äkta tjänster. Om det finns något intrång, vänligen kontakta oss via e-post.

Mail To:help@itsvse.com