Cet article est un article miroir de traduction automatique, veuillez cliquer ici pour accéder à l’article original.

Vue: 16332|Répondre: 4

[Algorithme] Algorithme SMS4, qui est un algorithme de cryptographie par blocs symétrique

[Copié le lien]
Publié sur 08/12/2015 21:49:35 | | |
C’est un algorithme de cryptographie par blocs, mais il utilise beaucoup de choses, et il existe maintenant un code source spécifique sur Internet, mais ce code a toujours une certaine valeur de recherche, si cela vous intéresse aussi, vous pouvez venir communiquer et apprendre ensemble. En fait, il n’est pas logique de vous donner un code complet, mais je joins quand même l’adresse complète du code au http://www.2cto.com/kf/201501/369374.html
Il y a aussi une boîte S dedans, très importante, utilisée dans l’algorithme DES, donc la suggestion de mon collègue est de comprendre clairement la boîte S de l’algorithme DES, afin que je puisse savoir de quoi parle la spécification de cet algorithme SMS4 ? La spécification n’est pas jointe.





Précédent:Il semble que cet endroit n’ait pas été mis à jour depuis longtemps, et je mettrai à jour le langage C tous les jours à l’avenir.
Prochain:Version complète de la vidéo en langage C
Publié sur 08/12/2015 22:19:05 |

Introduction à SMS4 :

Cet algorithme est un algorithme de regroupement. L’algorithme a une longueur de paquet de 128 bits et une longueur de clé de 128 bits, soit 16 octets. L’algorithme de chiffrement et l’algorithme d’expansion de clé adoptent tous deux une structure d’itération non linéaire de 32 tours. L’algorithme de déchiffrement a la même structure que l’algorithme de chiffrement, sauf que l’ordre d’utilisation de la clé ronde est inversé, et la clé de la roue de déchiffrement est l’ordre inverse de la clé de la roue de chiffrement. Dans toutes les classes de base de SMS4, vous verrez que les fonctions de base du chiffrement et du déchiffrement sont les mêmes, mais qu’un bit de drapeau de type int est nécessaire pour déterminer s’il est chiffré ou déchiffré.

Bases de l’algorithme de chiffrement SMS4 :



classe publique SMS4 {

    Statique privé final int ENCRYPT = 1 ;
    internement statique privé final int DECRYPT = 0 ;
    TOUR FINAL public statique = 32 ;
    bloc privé statique final int BLOCK = 16 ;

    octet privé[] 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) {
        retourner x << y | x >>> (32 - y) ;
    }

    private int ByteSub(int A) {
        retour (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) {
        retour B ^ Rotl(B, 2) ^ Rotl(B, 10) ^ Rotl(B, 18) ^ Rotl(B, 24) ;
        retour B^(B<<2|B>>>30)^(B<<10|B>>>22)^(B<<18|B>>>14)^(B<<24|B>>>8) ;
    }

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

    void SMS4Crypt(octet[] Entrée, octet[] Sortie, int[] rk) {
        int r, mid, x0, x1, x2, x3 ;
        int[] x = nouveau int[4] ;
        int[] tmp = new int[4] ;
        pour (int i = 0 ; J’ai < 4 ; i++) {
            tmp[0] = Entrée[0 + 4 * i] & 0xff ;
            tmp[1] = Entrée[1 + 4 * i] & 0xff ;
            tmp[2] = Entrée[2 + 4 * i] & 0xff ;
            tmp[3] = Entrée[3 + 4 * i] & 0xff ;
            x= tmp[0] << 24 | TMP[1] << 16 | TMP[2] << 8 | tmp[3] ;
            x=(Entrée[0+4*i]<<24| Entrée[1+4*i]<<16| Input[2+4*i]<<8| Entrée[3+4*i]) ;
        }
        pour (r = 0 ; r < 32 ; r += 4) {
            mid = x[1] ^ x[2] ^ x[3] ^ rk[r + 0] ;
            mid = ByteSub(mid) ;
            x[0] = x[0] ^ L1(milieu) ; x4

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

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

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

        Revers
        pour (int j = 0 ; j < 16 ; j += 4) {
            Sortie[j] = (octet) (x[3 - j / 4] >>> 24 & 0xFF) ;
            Sortie[j + 1] = (octet) (x[3 - j / 4] >>> 16 & 0xFF) ;
            Sortie[j + 2] = (octet) (x[3 - j / 4] >>> 8 & 0xFF) ;
            Sortie[j + 3] = (octet) (x[3 - j / 4] & 0xFF) ;
        }
    }

    private void SMS4KeyExt(byte[] Key, int[] rk, int CryptFlag) {
        int r, mid ;
        int[] x = nouveau int[4] ;
        int[] tmp = new int[4] ;
        pour (int i = 0 ; J’ai < 4 ; i++) {
            tmp[0] = Clé[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=Clé[0+4*i]<<24| Clé[1+4*i]<<16| Clé[2+4*i]<<8| Clé[3+4*i] ;
        }
        x[0] ^= 0xa3b1bac6 ;
        x[1] ^= 0x56aa3350 ;
        x[2] ^= 0x677d9197 ;
        x[3] ^= 0xb27022dc ;
        pour (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
        }

        Déchiffrer l’ordre de la clé de la roue : rk31, rk30,...,rk0
        if (CryptFlag == DECRYPT) {
            pour (r = 0 ; r < 16 ; r++) {
                mid = rk[r] ;
                rk[r] = rk[31 - r] ;
                rk[31 - r] = mid ;
            }
        }
    }

    public int sms4(octet[] entrée, int inLen, octet[] clé, octet[] sortie, int CryptFlag) {
        point d’intelligence = 0 ;
        int[] round_key = nouvelle int[ROUND] ;
        int[] round_key={0} ;
        SMS4KeyExt (clé, round_key, CryptFlag) ;
        Octet[] entrée = nouvel octet[16] ;
        Sortie octet[] = nouvel octet[16] ;

        while (inLen >= BLOCK) {
            entrée = Tableaux.copieDeRange(in, point, point + 16) ;
            sortie=Tableaux.copieDeRange(sortie, point, point+16) ;
            SMS4Crypt (entrée, sortie, round_key) ;
            System.arraycopy (sortie, 0, sortie, point, BLOCK) ;
            inLen -= BLOC ;
            point += BLOCAGE ;
        }

        retour 0 ;
    }
}

Interface externe intégrée :

Sur la base de cette classe de base, les interfaces principales sont les suivantes :



octet statique privé[] encode16(octet[] plain, octet[] clé) ;
octet statique privé[] décode16(chiffre d’octet[] clé, clé d’octet[]) ;
octet statique privé[] encode32(byte[] plain, byte[] key) ;
octet statique privé[] décode32(chiffre d’octet, clé d’octet[] ;
octet statique public[] encodeSMS4(octet[] plain, clé d’octet[] ;
octet statique public[] decodeSMS4(octet[] chiffre, clé d’octet[] ;
décodeur statique public StringSMS4toString(byte[] chiffre, clé d’octet[] ;

encode16(octet[], octet[]) est une interface pour le chiffrement des clés de texte clair 16 bits et 16 bits ;
Octet statique privé[] Decode16(Chiffre d’octet[] clé d’octet[]) : est une interface pour déchiffrer le texte chiffré 16 bits et la clé 16 bits ;
Octet statique privé[] encode32(octet[] plain, clé d’octet[] : Il s’agit d’une interface qui chiffre le texte clair 32 bits et les clés 16 bits.
Byte statique privé[] décode32(octet[] chiffre, clé d’octet[] : Il s’agit d’une interface pour déchiffrer le texte chiffré 32 bits et les clés 16 bits.
octet statique public[] encodeSMS4(octet[] plain, clé d’octet[] : Il s’agit d’une interface qui chiffre le texte clair et les clés de 16 bits avec un nombre illimité d’octets.
octet statique public[] decodesSMS4(octet[] chiffre, clé d’octet[] : Il s’agit d’une interface pour déchiffrer le texte chiffré et les clés 16 bits avec un nombre illimité d’octets.
décodeage statique public StringSMS4toString(byte[] chiffre, clé d’octet[] : Il s’agit d’une interface pour déchiffrer des octets illimités de texte chiffré et de clés 16 bits.
Code de méthode d’interface :



byte statique public[] encodeSMS4(String wordtext, byte[] key) {
        if (texte clair == null || texte clair.égales()) {
            retourner nul ;
        }
        pour (int i = texte clair.getBytes().length % 16 ; J'< 16 ans ; i++) {
            texte clair += '' ;
        }
        
        return SMS4.encodeSMS4(wordtext.getBytes(), key) ;
    }
   
    /**
     * Chiffrement SMS4 avec longueur illimitée de texte en clair
     *
     * @param texte en clair
     * @param clé
     * @return
     */
    octet statique public[] encodeSMS4(octet[] texte clair, clé d’octet[] {
        octet[] texte chiffré = nouvel octet[wordtext.length] ;
        
        int k = 0 ;
        int plainLen = wordtext.length ;
        tandis que (k + 16 <= plainLen) {
            octet[] cellPlain = nouvel octet[16] ;
            pour (int i = 0 ; J'< 16 ans ; i++) {
                cellPlain= texte clair[k + i] ;
            }
            octet[] cellCipher = encode16(cellPlain, clé) ;
            pour (int i = 0 ; i < cellCipher.length ; i++) {
                texte chiffré[k + i] = chiffre de cellule;
            }
            
            k += 16 ;
        }

        retourner le texte chiffré ;
    }

    /**
     * Déchiffrement SMS4 sans limite de longueur du texte clair
     *
     * @param texte chiffré
     * @param clé
     * @return
     */
    octet statique public[] decodeSMS4(octet[] texte chiffré, clé d’octet[] {
        octet[] texte clair = nouvel octet[crithertext.length] ;
        
        int k = 0 ;
        int chiffre Len = chiffretexte.longueur ;
        tandis que (k + 16 <= cipherLen) {
            octet[] cellCipher = nouvel octet[16] ;
            pour (int i = 0 ; J'< 16 ans ; i++) {
                cellCipher= texte chiffré[k + i] ;
            }
            octet[] cellPlain = decode16(cellCipher, key) ;
            pour (int i = 0 ; i < cellPlain.length ; i++) {
                texte clair[k + i] = cellPlain;
            }
            
            k += 16 ;
        }
        
        retourner le texte en clair ;
    }

    /**
     * Déchiffrer pour obtenir des chaînes de texte clair
     * @param texte chiffré
     * @param clé
     * @return
     */
    public static String decodeSMS4toString(byte[] crithertext, byte[] key) {
        octet[] texte clair = nouvel octet[crithertext.length] ;
        texte clair = decodeSMS4(texte chiffré, clé) ;
        retourner nouvelle chaîne (texte clair) ;
    }

    /**
     * Seul le texte clair 16 bits est chiffré
     *
     * @param texte en clair
     * @param clé
     * @return
     */
    Octet statique privé[] encode16(octet[] texte clair, octet[] clé) {
        Octet[] chiffre = nouvel octet[16] ;
        SMS4 sm4 = nouveau SMS4() ;
        sm4.sms4 (texte clair, 16, clé, chiffre, CRYPTAGE) ;

        chiffrer à retourner ;
    }

    /**
     * Seul le texte chiffré 16 bits est déchiffré
     *
     * @param texte en clair
     * @param clé
     * @return
     */
    Octet statique privé[] Decode16(octet[] texte chiffré, octet[] key) {
        byte[] plain = nouvel octet[16] ;
        SMS4 sm4 = nouveau SMS4() ;
        sm4.sms4 (texte chiffré, 16, clé, plain, DECRYPT) ;

        retour plain ;
    }
Je n’introduirai pas ici uniquement le chiffrement du texte clair 32 bits, qui est très similaire à la méthode du texte clair seulement 16 bits.


L’algorithme de base pour le chiffrement et le déchiffrement sans limiter la longueur du texte clair repose sur cette base de chiffrement et déchiffrement de seulement 16 bits. Pour le texte clair de plus de 16 bits, le chiffrement des paquets est utilisé ici. Si vous rencontrez du texte clair comme 30 bits qui ne peut pas être divisible par 16, une façon de le remplir est de le faire divisible par 16. En principe, seul le plus petit nombre peut être divisé par 16, bien sûr, si vous êtes satisfait, peu importe si vous l’agrandissez, car c’est le symbole de fermeture.

Le chiffrement des paquets consiste à chiffrer chaque texte clair de 16 bits une fois, puis à réassembler le texte chiffré de 16 bits en un nouveau texte chiffré. Lors du processus de déchiffrement, il est également divisé en une seule pièce de 16 bits, puis plusieurs de ces textes déchiffrés sont réassemblés en un nouveau texte clair.



Démonstration d’utilisation :



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

        Nouvelle chaîne = Codage, bonjour ! ; Texte clair
        
        octet[] enOut = SMS4.encodeSMS4(newString, clé) ;
        if (enOut == null) {
            rendre;
        }
        
        System.out.println (résultat du chiffrement :) ;
        printBit(enOut) ;

        octet[] deOut = SMS4.decodeSMS4(enOut, clé) ;
        System.out.println(
résultat de déchiffrement (octet de retour[]) :) ;
        printBit(deOut) ;

        String deOutStr = SMS4.decodeSMS4toString(enOut, key) ;
        System.out.println(
Déchiffrer le résultat (retourner la chaîne) :
+ deOutStr) ;
 Propriétaire| Publié sur 08/12/2015 22:25:41 |
Xiao Zhazha Publié le 8-12-2015 22:19
Introduction à SMS4 :

Cet algorithme est un algorithme de regroupement. L’algorithme a une longueur de paquet de 128 bits et une longueur de clé de 128 bits, soit 16 octets. ...

Tu copies le visage à l’intérieur ? J’ai exécuté cet algorithme plusieurs fois sur ordinateur, mais je ne suis toujours pas familier avec C# dans le débogage Java, et je ne connais peut-être pas chacune de ses étapes en détail, et je n’ai pas encore compris le principe de ses détails de travail. Java, sais-tu comment déboguer chaque variable ?
Publié sur 08/12/2015 22:40:48 |

Il doit servir à définir le point d’arrêt, la clé Myeclipse F5 et la clé F6 sont des débogages en une seule étape, F5 est un pas d’entrée, c’est-à-dire entrer le code de ligne à exécuter, F6 est un pas à pas, c’est-à-dire exécuter le code de ligne, puis passer à la ligne suivante
 Propriétaire| Publié sur 08/12/2015 23:07:37 |
Publié le 8-12-2015 à 22:40
Il doit servir à régler le point d’arrêt, la clé F5 et la clé F6 du point d’arrêt myeclipse sont toutes deux des débogages en une seule étape, F5 est un pas d’entrée, c’est-à-dire entrer le code de cette ligne pour exécuter ...

Je le sais tout à fait, mais je ne connais pas son processus précis, et je ne sais pas quand ni où j’en irai à quelle étape de la spécification. Ce serait bien que tu comprennes
Démenti:
Tous les logiciels, supports de programmation ou articles publiés par Code Farmer Network sont uniquement destinés à l’apprentissage et à la recherche ; Le contenu ci-dessus ne doit pas être utilisé à des fins commerciales ou illégales, sinon les utilisateurs assumeront toutes les conséquences. Les informations sur ce site proviennent d’Internet, et les litiges de droits d’auteur n’ont rien à voir avec ce site. Vous devez supprimer complètement le contenu ci-dessus de votre ordinateur dans les 24 heures suivant le téléchargement. Si vous aimez le programme, merci de soutenir un logiciel authentique, d’acheter l’immatriculation et d’obtenir de meilleurs services authentiques. En cas d’infraction, veuillez nous contacter par e-mail.

Mail To:help@itsvse.com