Artikel ini adalah artikel cermin dari terjemahan mesin, silakan klik di sini untuk melompat ke artikel aslinya.

Melihat: 16332|Jawab: 4

[Algoritma] Algoritma SMS4, yang merupakan algoritma kriptografi blok simetris

[Salin tautan]
Diposting pada 08/12/2015 21.49.35 | | |
Ini adalah algoritma kriptografi blok, tetapi dia menggunakan banyak hal, dan sekarang ada kode sumber tertentu di Internet, tetapi kode ini masih memiliki nilai penelitian tertentu, jika Anda juga tertarik dengan ini, Anda dapat masuk dan berkomunikasi serta belajar bersama. Faktanya, tidak masuk akal untuk memberi Anda kode lengkap, tetapi saya masih melampirkan alamat kode lengkap ke http://www.2cto.com/kf/201501/369374.html
Ada juga kotak S di dalamnya, yang sangat penting, yang digunakan dalam algoritma DES, jadi saran rekan saya kepada saya adalah memahami kotak S dari algoritma DES dengan jelas, sehingga saya dapat mengetahui apa yang dibicarakan spesifikasi dalam algoritma SMS4 ini? Spesifikasinya tidak terlampir.





Mantan:Tampaknya tempat ini sudah lama tidak diperbarui, dan saya akan memperbarui bahasa C setiap hari di masa mendatang.
Depan:Bahasa C, video versi lengkap
Diposting pada 08/12/2015 22.19.05 |

Pengenalan SMS4:

Algoritma ini adalah algoritma pengelompokan. Algoritma ini memiliki panjang paket 128 bit dan panjang kunci 128 bit, yaitu 16 byte. Baik algoritma enkripsi maupun algoritma ekspansi kunci mengadopsi struktur iterasi nonlinier 32 putaran. Algoritma dekripsi memiliki struktur yang sama dengan algoritma enkripsi, kecuali bahwa urutan penggunaan kunci bulat dibalik, dan kunci roda dekripsi adalah urutan terbalik dari kunci roda enkripsi. Di semua kelas dasar SMS4, Anda akan melihat bahwa fungsi dasar enkripsi dan dekripsi adalah sama, tetapi bit bendera tipe int diperlukan untuk menentukan apakah itu dienkripsi atau didekripsi.

Dasar-dasar algoritma enkripsi SMS4:



kelas publik SMS4 {

    int akhir statis pribadi ENCRYPT = 1;
    int final statis pribadi DECRYPT = 0;
    publik statis final int ROUND = 32;
    int akhir statis pribadi BLOK = 16;

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

    pribadi 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) {
        mengembalikan x << y | x >>> (32 - y);
    }

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

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

    private int L2(int B) {
        kembali B ^ Rotl(B, 13) ^ Rotl(B, 23);
        kembali B^(B<<13|B>>>19)^(B<<23|B>>>9);
    }

    void SMS4Crypt(byte[] Input, byte[] Output, int[] rk) {
        int r, pertengahan, x0, x1, x2, x3;
        int[] x = int[4] baru;
        int[] tmp = int baru[4];
        untuk (int i = 0; saya < 4; i++) {
            tmp[0] = Masukan[0 + 4 * i] & 0xff;
            tmp[1] = Masukan[1 + 4 * i] & 0xff;
            tmp[2] = Masukan[2 + 4 * i] & 0xff;
            tmp[3] = Masukan[3 + 4 * i] & 0xff;
            x= tmp[0] << 24 | tmp[1] << 16 | tmp[2] << 8 | tmp[3];
            x=(Masukan[0+4*i]<<24| Masukan[1+4*i]<<16| Masukan[2+4*i]<<8| Masukan [3 + 4 * i]);
        }
        untuk (r = 0; r < 32; r += 4) {
            tengah = x[1] ^ x[2] ^ x[3] ^ rk[r + 0];
            mid = ByteSub(mid);
            x[0] = x[0] ^ L1(tengah); x4

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

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

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

        Terbalik
        untuk (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);
            Keluaran[j + 2] = (byte) (x[3 - j / 4] >>> 8 & 0xFF);
            Keluaran[j + 3] = (byte) (x[3 - j / 4] & 0xFF);
        }
    }

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

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

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

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

        Dekripsi urutan kunci roda: rk31, rk30,...,rk0
        if (CryptFlag == DECRYPT) {
            untuk (r = 0; r < 16; r++) {
                tengah = rk[r];
                rk[r] = rk[31 - r];
                rk[31 - r] = tengah;
            }
        }
    }

    public int sms4(byte[] in, int inLen, byte[] key, byte[] out, int CryptFlag) {
        titik int = 0;
        int[] round_key = int[ROUND] baru;
        int[] round_key={0};
        SMS4KeyExt(kunci, round_key, CryptFlag);
        byte[] input = byte baru[16];
        keluaran byte[] = byte baru[16];

        sementara (inLen >= BLOCK) {
            masukan = Arrays.copyOfRange(dalam, titik, titik + 16);
            output=Arrays.copyOfRange(keluar, titik, titik+16);
            SMS4Crypt (input, output, round_key);
            System.arraycopy (keluaran, 0, keluar, titik, BLOK);
            inLen -= BLOK;
            titik += BLOK;
        }

        mengembalikan 0;
    }
}

Antarmuka eksternal yang dikemas:

Berdasarkan kelas dasar ini, antarmuka utamanya adalah sebagai berikut:



private static byte[] encode16(byte[] plain, byte[] key);
byte statis pribadi[] decode16(sandi byte[], kunci byte[]);
private static byte[] encode32(byte[] plain, byte[] key);
byte statis pribadi[] decode32(sandi byte[], byte[], kunci byte[]);
byte statis publik[] mengkodekan SMS4(byte[] polos, kunci byte[]);
byte statis publik[] decodeSMS4(sandi byte[], byte[]);
dekode String statis publikSMS4toString(sandi byte[], byte[]);

encode16(byte[], byte[]) adalah antarmuka untuk enkripsi untuk teks biasa 16-bit dan kunci 16-bit;
Private Static Byte[] Decode16(Byte[] Cipher, Byte[] Key): adalah antarmuka untuk mendekripsi teks sandi 16-bit dan kunci 16-bit;
private static byte[] encode32(byte[] plain, byte[] key): Ini adalah antarmuka yang mengenkripsi teks biasa 32-bit dan kunci 16-bit.
private static byte[] decode32(byte[] cipher, byte[] key): Ini adalah antarmuka untuk mendekripsi ciphertext 32-bit dan kunci 16-bit.
public static byte[] encodeSMS4(byte[] plain, byte[] key): Ini adalah antarmuka yang mengenkripsi teks biasa dan kunci 16-bit dengan jumlah byte yang tidak terbatas.
public static byte[] decodeSMS4(byte[] cipher, byte[] key): Ini adalah antarmuka untuk mendekripsi ciphertext dan kunci 16-bit dengan jumlah byte yang tidak terbatas.
dekode String statis publikSMS4toString(byte[] cipher, byte[] key): Ini adalah antarmuka untuk mendekripsi byte teks sandi dan kunci 16-bit tanpa batas.
Kode metode antarmuka:



publik statis byte[] encodeSMS4(String plaintext, byte[] key) {
        if (plaintext == null || plaintext.equals()) {
            mengembalikan null;
        }
        for (int i = plaintext.getBytes().length % 16; saya < 16; i++) {
            teks biasa += '';
        }
        
        mengembalikan SMS4.encodeSMS4(plaintext.getBytes(), kunci);
    }
   
    /**
     * Enkripsi SMS4 dengan panjang teks biasa tak terbatas
     *
     * @param teks biasa
     * Kunci @param
     * @return
     */
    byte statis publik[] encodeSMS4(byte[] plaintext, byte[] key) {
        byte[] ciphertext = byte baru[plaintext.length];
        
        int k = 0;
        int plainLen = plaintext.length;
        sementara (k + 16 <= plainLen) {
            byte[] cellPlain = byte baru[16];
            untuk (int i = 0; saya < 16; i++) {
                selPolos= teks biasa[k + i];
            }
            byte[] cellCipher = encode16(cellPlain, kunci);
            untuk (int i = 0; i < cellCipher.length; i++) {
                ciphertext[k + i] = cellCipher;
            }
            
            k += 16;
        }

        mengembalikan teks sandi;
    }

    /**
     * Dekripsi SMS4 tanpa batasan panjang teks biasa
     *
     * @param ciphertext
     * Kunci @param
     * @return
     */
    byte statis publik[] decodeSMS4(byte[] ciphertext, byte[] key) {
        byte[] plaintext = byte baru[ciphertext.length];
        
        int k = 0;
        int cipherLen = ciphertext.length;
        sementara (k + 16 <= cipherLen) {
            byte[] cellCipher = byte baru[16];
            untuk (int i = 0; saya < 16; i++) {
                selSencip= teks sandi[k + i];
            }
            byte[] cellPlain = decode16(cellCipher, kunci);
            untuk (int i = 0; i < cellPlain.length; i++) {
                plaintext[k + i] = cellPlain;
            }
            
            k += 16;
        }
        
        mengembalikan teks biasa;
    }

    /**
     * Dekripsi untuk mendapatkan string teks biasa
     * @param ciphertext
     * Kunci @param
     * @return
     */
    publik statis String decodeSMS4toString(byte[] ciphertext, byte[] key) {
        byte[] plaintext = byte baru[ciphertext.length];
        plaintext = decodeSMS4(ciphertext, kunci);
        mengembalikan String baru (teks biasa);
    }

    /**
     * Hanya teks biasa 16-bit yang dienkripsi
     *
     * @param teks biasa
     * Kunci @param
     * @return
     */
    private static byte[] encode16(byte[] plaintext, byte[] key) {
        byte[] cipher = byte baru[16];
        SMS4 sm4 = new SMS4();
        sm4.sms4(teks biasa, 16, kunci, sandi, ENKRIPSI);

        sandi kembali;
    }

    /**
     * Hanya teks sandi 16-bit yang didekripsi
     *
     * @param teks biasa
     * Kunci @param
     * @return
     */
    byte statis privat[] decode16(byte[] ciphertext, kunci byte[]) {
        byte[] plain = byte baru[16];
        SMS4 sm4 = new SMS4();
        sm4.sms4(teks sandi, 16, kunci, polos, DEKRIPSI);

        kembali polos;
    }
Saya tidak akan hanya memperkenalkan enkripsi teks biasa 32-bit di sini, yang sangat mirip dengan metode teks biasa hanya 16-bit.


Algoritme dasar untuk enkripsi dan dekripsi tanpa membatasi panjang teks biasa didasarkan pada dasar ini untuk mengenkripsi dan mendekripsi hanya 16 bit. Untuk teks biasa yang lebih besar dari 16 bit, enkripsi paket digunakan di sini. Jika Anda menemukan teks biasa seperti 30 bit yang tidak dapat dibagi 16, cara untuk mengisinya adalah dengan membuatnya sampai habis dibagi 16. Pada prinsipnya, hanya angka terkecil yang dapat dibagi dengan 16, tentu saja, jika Anda senang, tidak masalah jika Anda membuatnya lebih besar, karena itu adalah simbol penutup.

Enkripsi paket adalah mengenkripsi setiap teks biasa 16-bit sekali, dan kemudian menyusun kembali teks sandi 16-bit terenkripsi menjadi teks sandi baru. Dalam proses dekripsi, itu juga dibagi menjadi satu bagian 16-bit, dan kemudian beberapa teks biasa yang didekripsi ini dirakit kembali menjadi teks biasa baru.



Demonstrasi penggunaan:



kunci
        kunci byte[] = { 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 = Pengkodean, halo!; Teks biasa
        
        byte[] enOut = SMS4.encodeSMS4(newString, kunci);
        if (enOut == null) {
            kembali;
        }
        
        System.out.println(hasil enkripsi:);
        printBit(enOut);

        byte[] deOut = SMS4.decodeSMS4(enOut, kunci);
        Sistem.keluar.println(
hasil dekripsi (kembalikan byte[]) :);
        printBit(deOut);

        String deOutStr = SMS4.decodeSMS4toString(enOut, kunci);
        Sistem.keluar.println(
Dekripsi hasilnya (kembalikan String):
+ deOutStr);
 Tuan tanah| Diposting pada 08/12/2015 22.25.41 |
Xiao Zhazha Dipaparkan pada 2015-12-8 22:19
Pengenalan SMS4:

Algoritma ini adalah algoritma pengelompokan. Algoritma ini memiliki panjang paket 128 bit dan panjang kunci 128 bit, yaitu 16 byte. ...

Apakah Anda meniru wajah di dalamnya? Saya telah menjalankan algoritma ini di komputer beberapa kali, tetapi saya masih belum terbiasa dengan C# dalam debugging Java, dan saya mungkin tidak mengetahui setiap langkahnya secara rinci, dan saya belum mengetahui prinsip detail pekerjaannya. java, tahu cara men-debug setiap variabelnya?
Diposting pada 08/12/2015 22.40.48 |

Seharusnya untuk mengatur titik henti, kunci F5 titik henti myeclipse dan kunci F6 adalah debugging satu langkah, F5 adalah langkah masuk, yaitu, masukkan kode baris untuk dieksekusi, F6 adalah langkah di atas, yaitu, jalankan kode baris, lompat ke baris berikutnya
 Tuan tanah| Diposting pada 08/12/2015 23.07.37 |
Diterbitkan pada 2015-12-8 22:40
Seharusnya untuk mengatur titik henti, kunci F5 titik henti myeclipse dan kunci F6 keduanya adalah debugging satu langkah, F5 adalah langkah masuk, yaitu, masukkan kode baris ini untuk mengeksekusi ...

Saya pasti tahu, tetapi saya tidak tahu proses spesifiknya, dan saya tidak tahu kapan dan di mana saya akan sampai ke langkah apa dalam spesifikasi. Alangkah baiknya jika Anda mengerti
Sanggahan:
Semua perangkat lunak, materi pemrograman, atau artikel yang diterbitkan oleh Code Farmer Network hanya untuk tujuan pembelajaran dan penelitian; Konten di atas tidak boleh digunakan untuk tujuan komersial atau ilegal, jika tidak, pengguna akan menanggung semua konsekuensi. Informasi di situs ini berasal dari Internet, dan sengketa hak cipta tidak ada hubungannya dengan situs ini. Anda harus sepenuhnya menghapus konten di atas dari komputer Anda dalam waktu 24 jam setelah pengunduhan. Jika Anda menyukai program ini, harap dukung perangkat lunak asli, pembelian pendaftaran, dan dapatkan layanan asli yang lebih baik. Jika ada pelanggaran, silakan hubungi kami melalui email.

Mail To:help@itsvse.com