擴散加密算法

擴散加密算法是一種使用擴散算法進行數據加密/解密的算法。它使用擴散算法的原理,在處理過程中加入密匙,從而達到數據加密的目的。擴散算法有著完美的擴散率,進行數據加密可謂是“本職所在”。

基本介紹

  • 中文名:擴散加密算法
  • 外文名:Diffusion Encryption Algorithm
  • 用途:數據加密
  • 標籤:數據加密 加密算法 加密技術
擴散算法介紹,加密原理,加密過程,算法特性,加密模式,代碼實現,

擴散算法介紹

擴散算法是一種數據處理方法,目的在於通過擴散處理使得元素之間相互影響,從而實現完全的雪崩效應。雪崩效應是指原始輸入中的微小變化,經過積累發展後而造成輸出的巨大改變。而完全的雪崩效應,對於輸入中任意的微小變化都會造成輸出全部產生改變(100%的擴散率)。
擴散算法通過在元素之間建立擴散路徑,使元素沿著該路徑向其他元素擴散。每一個元素都沿著指定的路徑擴散,從而使元素間相互發生影響。
擴散算法的核心在於擴散過程,擴散過程由擴散網路決定。所謂擴散,是指元素傳遞影響的過程,若元素A擴散到元素B,則當A發生改變時,B也發生改變。
若有N(N>=1)個元素組成的集合M。通過一定的規則使M中的元素相對應,如M1(起點)對應M4(終點),M4對應M8,M8對應M2,M2對應M6…,描述為Mi向Mj擴散,記作Mi→Mj;分別取出相對應的元素並組成表達式,通過一定的方法對表達式進行處理,再使用處理的結果更新被對應的元素(終點)。當起點元素髮生改變時,終點元素也發生改變;在處理的過程中這種改變會發生傳遞,進而影響其他元素,最乃體終影響所有元素。
在上述過程中,元素間的對應關係用擴散路徑(以下簡稱路徑)表示,起點元素(Mi)叫做原體,終點元素(Mj)叫做受體;由元素組成的表達式叫做擴算式;對擴算式的處理叫做擴協喇設散運算(為防止受體丟失,擴散運算時需加入受體一同運算);所有路徑的集合叫做擴散網路(以下簡稱網路);對整個網路執行一次擴散叫做一個周期。
建立網路時,若要達到100%的擴散率,必須要保證所建立的網路對於每一個輸入元素都能影響任何一個輸出元素;局乘榆每個擴散式的擴散運算都必須滿足原體中任意元素的變化都將引起受體的變化(受體為元素組時,則元素組內的每一個元素都要發生變化)。

加密原理

擴散加密算法使用擴散算法的原理進行加密/解密。擴散算法有著良好的擴展性,可加入任意數據一同參與處理。因此,將密匙作為參與處理的分組一同建立路徑,可是密匙具有多樣化的處理;使用各種各樣的函式進行擴散運算,可使同樣的加密變得豐富多樣。
圖1(有序的網路-加密/解密)圖1(有序的網路-加密/解密)
參照圖1所示,X、Y為兩個明文分組,K為加密所用的密匙,各分組長度均為8,方框中的數字為元素索引;連線方框之間的線條叫做擴散路徑(以下簡稱路徑),X、Y到K的同一個元素上連線應表示為連通的(此處做了簡化才斷開顯示)。虛線表示X中第一個元素X[0]完成完全擴散所走的路徑;元素索引上方的“*”號表示被X[0]所影響的元素,因不乃匪挨乃更新K的元素,所以K的元素不發生改變(可按需要更新K的元素);所有路徑的集合叫做擴散網路(以下簡稱網路)。整個擴散過程共分為4個擴散階段(擴散階段的數量與分組數量和分組內元素數量有關),執行擴散過程需按從乎料墓擔上到下或者從下到上順序執行。

加密過程

參照圖1
第一步:建立擴散網路,將分組中的元素以某種規則建立網路(有序或無遙捉祝序);所建立的網路必須滿足對於每一個輸入元素(X、Y、K)都能通過該網路擴散到任意一個輸出元素中(X、Y)。
第二步:以路徑為基礎建立擴散式,擴散式的建立是為確認參與擴散運算的元素。如:
X[0]+K[0]+Y[4]→Y[4],Y[4]+K[0]+X[0]→X[0];
X[0]+K[0]+Y[2]→Y[2],Y[2]+K[0]+X[0]→X[0];
X[0]+K[0]+Y[1]→Y[1],Y[1]+K[0]+X[0]→X[0];
......
建立擴散式時,擴散式除包含路徑所連線的元素之外,還可以包含其他任意元素。
第三步:對擴散式進行擴散運算,並使用運算的結果更新受體。為防止受體丟失,需加入受體一同運算。如
Y[4]=FY(X[0], K[0], Y[4]), X[0] = FX(X[0], K[0], Y[4])。函式FX, FY是可逆函式。
解密過程與加密相反。

算法特性

密匙長度任意
擴散算法支持任意長度、任意數量的分組進行處理,擴散加密算法同理。建議分組長度N滿足
,x>=0且x為整數。擴散加密可以實現密匙和明文長度不等同,密匙即可以比明文短,也可以比明文長,具體可根據需要設定。
運算速度快
擴散加密算法的核心代碼只有幾行,所使用的運算操作可以是速度極快的運算(如加法運算、異或(xor)運算、置換運算和移位運算),且只需少量的擴散階段即可完成明文塊的加密(設N為明文長度,則只需
個擴散階段)。在每一階的擴散處理都臭廈充可以使用並行處理,對於N長度的擴散處理,並行計算速度理論上比串列計算提高N倍。
圖2(無序網路)圖2(無序網路)
擴散加密不需要顯式的對明文進行分組,可以直接對緩衝區進行(並行)處理,省去了明文的複製操作,進一步減少處理時間。
靈活的處理方式
網路可以建立為有序的(圖1),也可以建立為無序的(圖2)。相同長度的分組,有多種網路建立方案;豐富的擴散式建立方式,擴散式除包含路徑所連線的元素之外,還可以包含其他任意元素;豐富擴散運算方式,擴散運算可以使用任何函式進行運算(若需解密,則要求函式可逆)。

加密模式

擴散算法其良好的擴展性,可有如下加密模式:
對稱分組加密:使用擴散算法進行加密,對每一組明文的加密都使用的相同的密匙(可以在每一階都使用不同的密匙)。
對稱流加密:僅使用擴散算法生成子密匙流(參見生成隨機數),再使用所生成的密匙流和明文進行異或運算(xor)即可得到密文。使用可靠的擴散運算(函式)再以消除線性,將使密匙重複變得遙遙無期。
對稱分組流加密:使用擴散算法以密匙為基礎生成子密匙流,再使用擴散算法對明文進行分組加密。此模式可以滿足對每一組明文的加密都使用不同的密匙。
半非對稱加密:套用擴散算法,可提高非對稱的加密效率。用非對稱加密數據時,不需要將整個明文組塊合成一個大整數進行加密,只需對明文中的各個元素(元素組)分別加密即可(密匙不同)。
此模式共分三次加密。設有明文M,長度為n;套用非對稱分別對M中的各個元素(M1,M2,M3…Mn)進行加密後得到T1;套用擴散算法對T1進行加密後得到T2;最後再次套用非對稱分別對T2中的各個元素加密得到密文C(密匙與第一次加密相同)。
全非對稱加密:設函式F與函式Fˊ為非對稱互斥函式,通過F(Fˊ)加密後的數據只能通過F’(F)進行解密。套用擴散算法,在進行擴散運算的過程中使用F(Fˊ)進行加密,用Fˊ(F)進行解密即可。

代碼實現

/** * <p> * 套用擴散算法進行數據加密和解密示例(以兩組為例,分別為X和Y)。 * </p> *  *  * @version 2.0 * @author Angel *  */public class CryptoDemo {    /*    * S盒子, 任意0~255之間的不重複隨機整數。 S盒子是用於數據加密時函式所使用的數據,用以消除線性。     * S盒子的隨機性將會影響加密質量。    */    //@formatter:off    public static final byte[] S = {         (byte)0xd9, (byte)0x25, (byte)0x48, (byte)0x5c, (byte)0x55, (byte)0xa0, (byte)0x3c, (byte)0x94,         (byte)0x83, (byte)0x36, (byte)0x11, (byte)0x74, (byte)0x69, (byte)0x2e, (byte)0x59, (byte)0x7b,         (byte)0xd1, (byte)0x23, (byte)0x70, (byte)0x75, (byte)0x3a, (byte)0xbf, (byte)0x8c, (byte)0xd8,         (byte)0x2f, (byte)0x34, (byte)0xb3, (byte)0x79, (byte)0xa4, (byte)0x27, (byte)0xa9, (byte)0x1d,         (byte)0xb0, (byte)0xc8, (byte)0x38, (byte)0x8f, (byte)0x49, (byte)0x8b, (byte)0x89, (byte)0x0f,         (byte)0x3b, (byte)0x92, (byte)0x33, (byte)0xcf, (byte)0xcd, (byte)0x1b, (byte)0x06, (byte)0xf0,         (byte)0xfb, (byte)0x82, (byte)0xbb, (byte)0xc6, (byte)0xf2, (byte)0x07, (byte)0x4e, (byte)0xe8,         (byte)0x77, (byte)0x6c, (byte)0x88, (byte)0x28, (byte)0xba, (byte)0xb9, (byte)0xe1, (byte)0xe9,         (byte)0xd7, (byte)0x4b, (byte)0x81, (byte)0xde, (byte)0x08, (byte)0x0d, (byte)0xfc, (byte)0x03,         (byte)0x87, (byte)0x56, (byte)0x14, (byte)0x0a, (byte)0x63, (byte)0x98, (byte)0x7a, (byte)0xf9,         (byte)0x2c, (byte)0x7e, (byte)0x13, (byte)0x7d, (byte)0x04, (byte)0x01, (byte)0x9e, (byte)0xbc,         (byte)0x41, (byte)0xdf, (byte)0x05, (byte)0x4f, (byte)0xfa, (byte)0x47, (byte)0x53, (byte)0xf8,         (byte)0x46, (byte)0x52, (byte)0x8e, (byte)0x4a, (byte)0x76, (byte)0x09, (byte)0x1e, (byte)0xd2,         (byte)0x2d, (byte)0x3e, (byte)0x61, (byte)0x5a, (byte)0x20, (byte)0x29, (byte)0xd0, (byte)0x16,         (byte)0xb4, (byte)0x67, (byte)0xbd, (byte)0x50, (byte)0x60, (byte)0x35, (byte)0x19, (byte)0xd5,         (byte)0xdd, (byte)0x8a, (byte)0xea, (byte)0xa5, (byte)0xac, (byte)0x1a, (byte)0x58, (byte)0x1f,         (byte)0x5d, (byte)0x40, (byte)0x6d, (byte)0x86, (byte)0xeb, (byte)0x42, (byte)0x02, (byte)0x00,         (byte)0xaa, (byte)0x9b, (byte)0xa1, (byte)0x7f, (byte)0xe4, (byte)0xb8, (byte)0xe6, (byte)0x21,         (byte)0x68, (byte)0x12, (byte)0xd6, (byte)0x4d, (byte)0x4c, (byte)0x62, (byte)0xc0, (byte)0x66,         (byte)0x0e, (byte)0x72, (byte)0x64, (byte)0xf6, (byte)0x80, (byte)0xb5, (byte)0xd4, (byte)0xf4,         (byte)0x84, (byte)0x9d, (byte)0x73, (byte)0x51, (byte)0xe3, (byte)0x26, (byte)0xf3, (byte)0x1c,         (byte)0x96, (byte)0xe2, (byte)0xcc, (byte)0x90, (byte)0xa3, (byte)0xc5, (byte)0xda, (byte)0xf7,         (byte)0xad, (byte)0x6b, (byte)0x44, (byte)0x31, (byte)0xdb, (byte)0xa7, (byte)0xd3, (byte)0xfd,         (byte)0xb2, (byte)0xcb, (byte)0xc7, (byte)0xf1, (byte)0x91, (byte)0x97, (byte)0xae, (byte)0xb6,         (byte)0x45, (byte)0xc4, (byte)0xec, (byte)0xc2, (byte)0xce, (byte)0x18, (byte)0x3d, (byte)0xbe,         (byte)0x7c, (byte)0xe5, (byte)0xb1, (byte)0xc9, (byte)0x0c, (byte)0x54, (byte)0x24, (byte)0x43,         (byte)0x30, (byte)0x2a, (byte)0xb7, (byte)0xca, (byte)0x6e, (byte)0xc3, (byte)0x5b, (byte)0x9f,         (byte)0x10, (byte)0xee, (byte)0x8d, (byte)0x95, (byte)0x32, (byte)0xc1, (byte)0x57, (byte)0x0b,         (byte)0xed, (byte)0x99, (byte)0x5f, (byte)0xdc, (byte)0xaf, (byte)0x17, (byte)0xef, (byte)0xff,         (byte)0x9c, (byte)0x9a, (byte)0x85, (byte)0x2b, (byte)0xab, (byte)0x5e, (byte)0xf5, (byte)0x6f,         (byte)0xa6, (byte)0x39, (byte)0xa8, (byte)0x6a, (byte)0x3f, (byte)0x93, (byte)0x65, (byte)0xe0,         (byte)0xfe, (byte)0x71, (byte)0x15, (byte)0x78, (byte)0x22, (byte)0xa2, (byte)0x37, (byte)0xe7, };    /*    * 逆S盒子,設v是一個0~255之間的整數,_S必須滿足_S[S[v]] = v.    */    public static final byte[] _S = {        (byte)0x1c, (byte)0xc2, (byte)0xb1, (byte)0x88, (byte)0x20, (byte)0x6a, (byte)0x03, (byte)0xc8,         (byte)0xba, (byte)0xa6, (byte)0xf9, (byte)0xa5, (byte)0x96, (byte)0x5a, (byte)0xe2, (byte)0xa3,         (byte)0x2b, (byte)0x3c, (byte)0xa9, (byte)0x75, (byte)0x87, (byte)0x5b, (byte)0x28, (byte)0x3d,         (byte)0xcd, (byte)0x61, (byte)0x69, (byte)0x09, (byte)0x68, (byte)0x21, (byte)0xd6, (byte)0x57,         (byte)0x85, (byte)0x0a, (byte)0x7d, (byte)0x2c, (byte)0x9c, (byte)0xfb, (byte)0x70, (byte)0x35,         (byte)0x72, (byte)0x9e, (byte)0x08, (byte)0x6c, (byte)0xfc, (byte)0x30, (byte)0x3e, (byte)0x64,         (byte)0xa0, (byte)0x4a, (byte)0x38, (byte)0x9a, (byte)0xf0, (byte)0x1d, (byte)0x3f, (byte)0x52,         (byte)0x0d, (byte)0xbd, (byte)0xbc, (byte)0xb2, (byte)0xd7, (byte)0xf2, (byte)0x47, (byte)0x95,         (byte)0x16, (byte)0x5d, (byte)0x43, (byte)0x55, (byte)0x41, (byte)0x2d, (byte)0xb3, (byte)0x3a,         (byte)0xa1, (byte)0x4b, (byte)0x53, (byte)0x39, (byte)0x2a, (byte)0xac, (byte)0x44, (byte)0xab,         (byte)0xee, (byte)0x90, (byte)0xe7, (byte)0x36, (byte)0x1e, (byte)0xf7, (byte)0x12, (byte)0xc0,         (byte)0x97, (byte)0x80, (byte)0x2e, (byte)0x34, (byte)0x63, (byte)0xf8, (byte)0xc3, (byte)0xd9,         (byte)0x77, (byte)0xbe, (byte)0x29, (byte)0x24, (byte)0x0c, (byte)0x49, (byte)0x0e, (byte)0x7f,         (byte)0xb7, (byte)0xbf, (byte)0xfa, (byte)0x04, (byte)0x42, (byte)0x60, (byte)0x59, (byte)0x66,         (byte)0xaf, (byte)0x3b, (byte)0xb4, (byte)0x26, (byte)0x1f, (byte)0x6e, (byte)0x1b, (byte)0x2f,         (byte)0xdf, (byte)0xcf, (byte)0xdc, (byte)0xb0, (byte)0xc6, (byte)0x37, (byte)0x78, (byte)0x67,         (byte)0x07, (byte)0xd5, (byte)0x06, (byte)0xc7, (byte)0xd4, (byte)0xda, (byte)0xae, (byte)0xb5,         (byte)0xc4, (byte)0xe5, (byte)0xcb, (byte)0x5f, (byte)0x4c, (byte)0xc5, (byte)0x18, (byte)0xa7,         (byte)0x58, (byte)0x8a, (byte)0x11, (byte)0xd2, (byte)0xca, (byte)0x7a, (byte)0xef, (byte)0x65,         (byte)0x45, (byte)0xf6, (byte)0xfd, (byte)0xad, (byte)0x27, (byte)0x9f, (byte)0xe6, (byte)0xff,         (byte)0xec, (byte)0x0f, (byte)0x7c, (byte)0x91, (byte)0x4e, (byte)0x81, (byte)0x25, (byte)0x9d,         (byte)0xbb, (byte)0xed, (byte)0x51, (byte)0x6b, (byte)0xd0, (byte)0xe8, (byte)0x8d, (byte)0x98,         (byte)0x50, (byte)0x33, (byte)0x5c, (byte)0xaa, (byte)0x99, (byte)0xf5, (byte)0x89, (byte)0x7e,         (byte)0xa2, (byte)0x71, (byte)0x94, (byte)0xa8, (byte)0x86, (byte)0x46, (byte)0xe9, (byte)0x74,         (byte)0x01, (byte)0xd8, (byte)0x05, (byte)0x4f, (byte)0x32, (byte)0x40, (byte)0xe0, (byte)0xdd,         (byte)0x82, (byte)0xa4, (byte)0xe3, (byte)0xc1, (byte)0x14, (byte)0x13, (byte)0xb6, (byte)0xdb,         (byte)0xf3, (byte)0x23, (byte)0xe1, (byte)0xde, (byte)0x4d, (byte)0x84, (byte)0xc9, (byte)0x5e,         (byte)0xfe, (byte)0x8e, (byte)0xeb, (byte)0x56, (byte)0x83, (byte)0x00, (byte)0x6d, (byte)0x62,         (byte)0xf4, (byte)0xea, (byte)0x15, (byte)0xcc, (byte)0x1a, (byte)0x76, (byte)0x17, (byte)0xf1,         (byte)0x10, (byte)0x8c, (byte)0x73, (byte)0x31, (byte)0xb9, (byte)0x02, (byte)0x54, (byte)0x6f,         (byte)0x92, (byte)0x79, (byte)0x19, (byte)0x22, (byte)0x8b, (byte)0x93, (byte)0xe4, (byte)0xb8,         (byte)0x7b, (byte)0x9b, (byte)0xce, (byte)0x8f, (byte)0x48, (byte)0xd3, (byte)0xd1, (byte)0x0b, };    static long LONG_TEN = 100000000000000L;        int E = 2;        // 額外的循環數量E    int N;            // 分組長度N    int P;            // 基於長度N的完美長度。    int round;        // 用於加密的輪數(對應擴散階段的數量)。    byte[][] KX;    // 用於加密的子密匙(X), 每一輪的密匙都不相同。    byte[][] KY;    // 用於加密的子密匙(Y), 每一輪的密匙都不相同。    // @formatter:on    public CryptoDemo(int keySize) { // keySize:byte        N = keySize;        int G = (int) Math.ceil(Math.log(N) / Math.log(2)); // 計算以2為底N的對數,並向上取整        P = 1 << G; // P=2的G次方        round = G + E;        KX = new byte[round][];        KY = new byte[round][];    }    /**    * 生成子密匙, 通過擴散算法使得原密匙的每一個密匙都影響其它任何一個密匙。    * <p>    * 每個周期完成後,將本周的輸出作為下一個周期的輸入再計運算元密匙。共需round個周期。    * </p>    *     * @param kx    *            原始密匙X    * @param ky    *            原始密匙Y    */    public void init(byte[] kx, byte[] ky) {        for (int i = 0; i < round; i++) {            init(kx, ky, i);        }    }    Function FKx = new XKey(); // 用於生成子密匙的函式X    Function FKy = new YKey(); // 用於生成子密匙的函式Y    private void init(byte[] kx, byte[] ky, int index) {        int l = 0;        for (int i = 1; i <= round; i++) {            for (int r = 0; r < N; r++) {                ky[r] = (byte) (FKy.call(kx[l], ky[r]) & 255);                kx[l] = (byte) (FKx.call(kx[l], ky[r]) & 255);                l = (++l) % N;            }            l = P >> i;        }        KX[index] = kx.clone();        KY[index] = ky.clone();    }    /**    * 用於生成子密匙的函式X實現。    *     * @author Angel    *     */    class XKey implements Function {        int A = 11;        int B = 21;        int C = 31;        @Override        public int call(int x, int y, int... values) {            return A * x * x + B * y + C;        }    }    /**    * 用於生成子密匙的函式Y實現。    *     * @author Angel    *     */    class YKey implements Function {        long C = 0x6180339887L;        @Override        public int call(int x, int y, int... values) {            double a = Math.sin(x);            double b = Math.cos(y);            long v = (long) ((a + b) * LONG_TEN + C);            return (int) (v & 0xffffffff);        }    }    // ----------------------------------------------------------------------------    Function Ex = new XEncrypt(); // 用於加密進行擴散運算的函式X    Function Ey = new YEncrypt(); // 用於加密進行擴散運算的函式Y    /**    * 加密明文。次方法只加密一組數據,X,Y的長度為N。    *     * @param X    *            明文X    * @param Y    *            明文Y    */    public void encrypt(byte[] X, byte[] Y) {        int x = 0;        for (int i = 1, k = 0; i <= round; i++, k++) {            for (int y = 0; y < N; y++) {                Y[y] = (byte) Ey.call(X[x], Y[y], KY[k][y]);                X[x] = (byte) Ex.call(X[x], Y[y], KX[k][y]); // KX[k][x]                // 不建議使用%運算                // 當N&(N-1)=0時,可使用&運算,即N=2的j次方(j>0,且j為整數)                x = (++x) % N; // x = (++x) & (N-1);            }            x = P >> i;        }    }    /**    * 用於加密算法的函式X實現。    *     * @author Angel    *     */    class XEncrypt implements Function {        /**        * 由於java中byte的值域為[-128,127],因此需要將運算後的值加128以改變值域為[0,255](余同)。        *         * <p>        * 此處為行方便,特將key以其他參數的第0位傳入(余同)。        * </p>        */        @Override        public int call(int x, int y, int... values) {            // values[0] is key            return S[(x ^ values[0]) + 128] ^ y;        }    }    /**    * 用於加密算法的函式Y實現。    *     * @author Angel    *     */    class YEncrypt implements Function {        @Override        public int call(int x, int y, int... values) {            // values[0] is key            return S[(y ^ values[0]) + 128] ^ x;        }    }    // ------------------------------------------------------------------------    Function Dx = new XDecrypt(); // 用於解密進行擴散運算的函式X    Function Dy = new YDecrypt(); // 用於解密進行擴散運算的函式Y    /**    * 解密密文,次方法只解密一組數據,X,Y的長度為N。    *     * @param X    *            密文X,對應加密後所輸出的X    * @param Y    *            密文Y,對應加密後所輸出的Y    */    public void decrypt(byte[] X, byte[] Y) {        int x = 0;        int k = round - 1;        for (int i = 0; i < round; i++, k--) {            for (int y = 0; y < N; y++) {                X[x] = (byte) Dx.call(X[x], Y[y], KX[k][y]); // KX[k][x]                Y[y] = (byte) Dy.call(X[x], Y[y], KY[k][y]);                x = (++x) % N; // x=(++x)&(N-1); and N&(N-1)=0            }            x = (1 << i) % P; // x=(1<<i)&(P-1); and P&(P-1)=0        }    }    /**    * 用於解密算法的函式X實現。    *     * @author Angel    *     */    class XDecrypt implements Function {        @Override        public int call(int x, int y, int... values) {            // values[0] is key            return _S[(x ^ y) + 128] ^ values[0];        }    }    /**    * 用於解密算法的函式Y實現。    *     * @author Angel    *     */    class YDecrypt implements Function {        @Override        public int call(int x, int y, int... values) {            // values[0] is key            return _S[(x ^ y) + 128] ^ values[0];        }    }    // ---------------------------------------------------------------------------    static interface Function {        int call(int x, int y, int... values);    }    static void print(byte[] array) {        for (byte b : array) {            String s = Integer.toHexString(b & 0xff);            if (s.length() == 1) {                s = '0' + s;            }            System.out.print(s + ", ");        }    }    // --------------------------------------------------------------------------    /**    * 微變加密測試, 每次加密只需改變原輸入的一個元素(可以是密匙或者明文)。    * 不建議使用弱密匙,當所有密匙X的元素相等且所有密匙Y的元素都相等時為弱密匙,即:    * <p>    * KX[0]=KX[1]=KX[2]=...=KX[n-1]; KY[0]=KY[1]=KY[2]=...=KY[n-1];    * </P>    */    public static void microChangeTest() {        String line = "-------------------------------------------------------------------------------";        int length = 9;        byte[] KX = { 1, 1, 1, 1, 1, 1, 1, 1, 2 }; // 密匙X(不建議全部相等)        byte[] KY = { 1, 1, 1, 1, 1, 1, 1, 1, 2 }; // 密匙Y(不建議全部相等)        byte[] MX = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }; // 明文X        byte[] MY = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }; // 明文Y        CryptoDemo demo = new CryptoDemo(length);        for (int i = 0; i < 256; i++) {            demo.init(KX, KY); // 初始化密匙            byte[] TX = MX.clone();            byte[] TY = MY.clone();            System.out.print("明     文:");            print(TX);            print(TY);            System.out.println();            demo.encrypt(TX, TY);            System.out.print("加密後:");            print(TX);            print(TY);            System.out.println();            byte[] CX = TX.clone();            byte[] CY = TY.clone();            demo.decrypt(CX, CY);            System.out.print("解密後:");            print(CX);            print(CY);            System.out.println();            MX[0]++; // 更改原數據            System.out.println(line);        }    }    public static void main(String[] args) {        microChangeTest();    }}
第二步:以路徑為基礎建立擴散式,擴散式的建立是為確認參與擴散運算的元素。如:
X[0]+K[0]+Y[4]→Y[4],Y[4]+K[0]+X[0]→X[0];
X[0]+K[0]+Y[2]→Y[2],Y[2]+K[0]+X[0]→X[0];
X[0]+K[0]+Y[1]→Y[1],Y[1]+K[0]+X[0]→X[0];
......
建立擴散式時,擴散式除包含路徑所連線的元素之外,還可以包含其他任意元素。
第三步:對擴散式進行擴散運算,並使用運算的結果更新受體。為防止受體丟失,需加入受體一同運算。如
Y[4]=FY(X[0], K[0], Y[4]), X[0] = FX(X[0], K[0], Y[4])。函式FX, FY是可逆函式。
解密過程與加密相反。

算法特性

密匙長度任意
擴散算法支持任意長度、任意數量的分組進行處理,擴散加密算法同理。建議分組長度N滿足
,x>=0且x為整數。擴散加密可以實現密匙和明文長度不等同,密匙即可以比明文短,也可以比明文長,具體可根據需要設定。
運算速度快
擴散加密算法的核心代碼只有幾行,所使用的運算操作可以是速度極快的運算(如加法運算、異或(xor)運算、置換運算和移位運算),且只需少量的擴散階段即可完成明文塊的加密(設N為明文長度,則只需
個擴散階段)。在每一階的擴散處理都可以使用並行處理,對於N長度的擴散處理,並行計算速度理論上比串列計算提高N倍。
圖2(無序網路)圖2(無序網路)
擴散加密不需要顯式的對明文進行分組,可以直接對緩衝區進行(並行)處理,省去了明文的複製操作,進一步減少處理時間。
靈活的處理方式
網路可以建立為有序的(圖1),也可以建立為無序的(圖2)。相同長度的分組,有多種網路建立方案;豐富的擴散式建立方式,擴散式除包含路徑所連線的元素之外,還可以包含其他任意元素;豐富擴散運算方式,擴散運算可以使用任何函式進行運算(若需解密,則要求函式可逆)。

加密模式

擴散算法其良好的擴展性,可有如下加密模式:
對稱分組加密:使用擴散算法進行加密,對每一組明文的加密都使用的相同的密匙(可以在每一階都使用不同的密匙)。
對稱流加密:僅使用擴散算法生成子密匙流(參見生成隨機數),再使用所生成的密匙流和明文進行異或運算(xor)即可得到密文。使用可靠的擴散運算(函式)再以消除線性,將使密匙重複變得遙遙無期。
對稱分組流加密:使用擴散算法以密匙為基礎生成子密匙流,再使用擴散算法對明文進行分組加密。此模式可以滿足對每一組明文的加密都使用不同的密匙。
半非對稱加密:套用擴散算法,可提高非對稱的加密效率。用非對稱加密數據時,不需要將整個明文組塊合成一個大整數進行加密,只需對明文中的各個元素(元素組)分別加密即可(密匙不同)。
此模式共分三次加密。設有明文M,長度為n;套用非對稱分別對M中的各個元素(M1,M2,M3…Mn)進行加密後得到T1;套用擴散算法對T1進行加密後得到T2;最後再次套用非對稱分別對T2中的各個元素加密得到密文C(密匙與第一次加密相同)。
全非對稱加密:設函式F與函式Fˊ為非對稱互斥函式,通過F(Fˊ)加密後的數據只能通過F’(F)進行解密。套用擴散算法,在進行擴散運算的過程中使用F(Fˊ)進行加密,用Fˊ(F)進行解密即可。

代碼實現

/** * <p> * 套用擴散算法進行數據加密和解密示例(以兩組為例,分別為X和Y)。 * </p> *  *  * @version 2.0 * @author Angel *  */public class CryptoDemo {    /*    * S盒子, 任意0~255之間的不重複隨機整數。 S盒子是用於數據加密時函式所使用的數據,用以消除線性。     * S盒子的隨機性將會影響加密質量。    */    //@formatter:off    public static final byte[] S = {         (byte)0xd9, (byte)0x25, (byte)0x48, (byte)0x5c, (byte)0x55, (byte)0xa0, (byte)0x3c, (byte)0x94,         (byte)0x83, (byte)0x36, (byte)0x11, (byte)0x74, (byte)0x69, (byte)0x2e, (byte)0x59, (byte)0x7b,         (byte)0xd1, (byte)0x23, (byte)0x70, (byte)0x75, (byte)0x3a, (byte)0xbf, (byte)0x8c, (byte)0xd8,         (byte)0x2f, (byte)0x34, (byte)0xb3, (byte)0x79, (byte)0xa4, (byte)0x27, (byte)0xa9, (byte)0x1d,         (byte)0xb0, (byte)0xc8, (byte)0x38, (byte)0x8f, (byte)0x49, (byte)0x8b, (byte)0x89, (byte)0x0f,         (byte)0x3b, (byte)0x92, (byte)0x33, (byte)0xcf, (byte)0xcd, (byte)0x1b, (byte)0x06, (byte)0xf0,         (byte)0xfb, (byte)0x82, (byte)0xbb, (byte)0xc6, (byte)0xf2, (byte)0x07, (byte)0x4e, (byte)0xe8,         (byte)0x77, (byte)0x6c, (byte)0x88, (byte)0x28, (byte)0xba, (byte)0xb9, (byte)0xe1, (byte)0xe9,         (byte)0xd7, (byte)0x4b, (byte)0x81, (byte)0xde, (byte)0x08, (byte)0x0d, (byte)0xfc, (byte)0x03,         (byte)0x87, (byte)0x56, (byte)0x14, (byte)0x0a, (byte)0x63, (byte)0x98, (byte)0x7a, (byte)0xf9,         (byte)0x2c, (byte)0x7e, (byte)0x13, (byte)0x7d, (byte)0x04, (byte)0x01, (byte)0x9e, (byte)0xbc,         (byte)0x41, (byte)0xdf, (byte)0x05, (byte)0x4f, (byte)0xfa, (byte)0x47, (byte)0x53, (byte)0xf8,         (byte)0x46, (byte)0x52, (byte)0x8e, (byte)0x4a, (byte)0x76, (byte)0x09, (byte)0x1e, (byte)0xd2,         (byte)0x2d, (byte)0x3e, (byte)0x61, (byte)0x5a, (byte)0x20, (byte)0x29, (byte)0xd0, (byte)0x16,         (byte)0xb4, (byte)0x67, (byte)0xbd, (byte)0x50, (byte)0x60, (byte)0x35, (byte)0x19, (byte)0xd5,         (byte)0xdd, (byte)0x8a, (byte)0xea, (byte)0xa5, (byte)0xac, (byte)0x1a, (byte)0x58, (byte)0x1f,         (byte)0x5d, (byte)0x40, (byte)0x6d, (byte)0x86, (byte)0xeb, (byte)0x42, (byte)0x02, (byte)0x00,         (byte)0xaa, (byte)0x9b, (byte)0xa1, (byte)0x7f, (byte)0xe4, (byte)0xb8, (byte)0xe6, (byte)0x21,         (byte)0x68, (byte)0x12, (byte)0xd6, (byte)0x4d, (byte)0x4c, (byte)0x62, (byte)0xc0, (byte)0x66,         (byte)0x0e, (byte)0x72, (byte)0x64, (byte)0xf6, (byte)0x80, (byte)0xb5, (byte)0xd4, (byte)0xf4,         (byte)0x84, (byte)0x9d, (byte)0x73, (byte)0x51, (byte)0xe3, (byte)0x26, (byte)0xf3, (byte)0x1c,         (byte)0x96, (byte)0xe2, (byte)0xcc, (byte)0x90, (byte)0xa3, (byte)0xc5, (byte)0xda, (byte)0xf7,         (byte)0xad, (byte)0x6b, (byte)0x44, (byte)0x31, (byte)0xdb, (byte)0xa7, (byte)0xd3, (byte)0xfd,         (byte)0xb2, (byte)0xcb, (byte)0xc7, (byte)0xf1, (byte)0x91, (byte)0x97, (byte)0xae, (byte)0xb6,         (byte)0x45, (byte)0xc4, (byte)0xec, (byte)0xc2, (byte)0xce, (byte)0x18, (byte)0x3d, (byte)0xbe,         (byte)0x7c, (byte)0xe5, (byte)0xb1, (byte)0xc9, (byte)0x0c, (byte)0x54, (byte)0x24, (byte)0x43,         (byte)0x30, (byte)0x2a, (byte)0xb7, (byte)0xca, (byte)0x6e, (byte)0xc3, (byte)0x5b, (byte)0x9f,         (byte)0x10, (byte)0xee, (byte)0x8d, (byte)0x95, (byte)0x32, (byte)0xc1, (byte)0x57, (byte)0x0b,         (byte)0xed, (byte)0x99, (byte)0x5f, (byte)0xdc, (byte)0xaf, (byte)0x17, (byte)0xef, (byte)0xff,         (byte)0x9c, (byte)0x9a, (byte)0x85, (byte)0x2b, (byte)0xab, (byte)0x5e, (byte)0xf5, (byte)0x6f,         (byte)0xa6, (byte)0x39, (byte)0xa8, (byte)0x6a, (byte)0x3f, (byte)0x93, (byte)0x65, (byte)0xe0,         (byte)0xfe, (byte)0x71, (byte)0x15, (byte)0x78, (byte)0x22, (byte)0xa2, (byte)0x37, (byte)0xe7, };    /*    * 逆S盒子,設v是一個0~255之間的整數,_S必須滿足_S[S[v]] = v.    */    public static final byte[] _S = {        (byte)0x1c, (byte)0xc2, (byte)0xb1, (byte)0x88, (byte)0x20, (byte)0x6a, (byte)0x03, (byte)0xc8,         (byte)0xba, (byte)0xa6, (byte)0xf9, (byte)0xa5, (byte)0x96, (byte)0x5a, (byte)0xe2, (byte)0xa3,         (byte)0x2b, (byte)0x3c, (byte)0xa9, (byte)0x75, (byte)0x87, (byte)0x5b, (byte)0x28, (byte)0x3d,         (byte)0xcd, (byte)0x61, (byte)0x69, (byte)0x09, (byte)0x68, (byte)0x21, (byte)0xd6, (byte)0x57,         (byte)0x85, (byte)0x0a, (byte)0x7d, (byte)0x2c, (byte)0x9c, (byte)0xfb, (byte)0x70, (byte)0x35,         (byte)0x72, (byte)0x9e, (byte)0x08, (byte)0x6c, (byte)0xfc, (byte)0x30, (byte)0x3e, (byte)0x64,         (byte)0xa0, (byte)0x4a, (byte)0x38, (byte)0x9a, (byte)0xf0, (byte)0x1d, (byte)0x3f, (byte)0x52,         (byte)0x0d, (byte)0xbd, (byte)0xbc, (byte)0xb2, (byte)0xd7, (byte)0xf2, (byte)0x47, (byte)0x95,         (byte)0x16, (byte)0x5d, (byte)0x43, (byte)0x55, (byte)0x41, (byte)0x2d, (byte)0xb3, (byte)0x3a,         (byte)0xa1, (byte)0x4b, (byte)0x53, (byte)0x39, (byte)0x2a, (byte)0xac, (byte)0x44, (byte)0xab,         (byte)0xee, (byte)0x90, (byte)0xe7, (byte)0x36, (byte)0x1e, (byte)0xf7, (byte)0x12, (byte)0xc0,         (byte)0x97, (byte)0x80, (byte)0x2e, (byte)0x34, (byte)0x63, (byte)0xf8, (byte)0xc3, (byte)0xd9,         (byte)0x77, (byte)0xbe, (byte)0x29, (byte)0x24, (byte)0x0c, (byte)0x49, (byte)0x0e, (byte)0x7f,         (byte)0xb7, (byte)0xbf, (byte)0xfa, (byte)0x04, (byte)0x42, (byte)0x60, (byte)0x59, (byte)0x66,         (byte)0xaf, (byte)0x3b, (byte)0xb4, (byte)0x26, (byte)0x1f, (byte)0x6e, (byte)0x1b, (byte)0x2f,         (byte)0xdf, (byte)0xcf, (byte)0xdc, (byte)0xb0, (byte)0xc6, (byte)0x37, (byte)0x78, (byte)0x67,         (byte)0x07, (byte)0xd5, (byte)0x06, (byte)0xc7, (byte)0xd4, (byte)0xda, (byte)0xae, (byte)0xb5,         (byte)0xc4, (byte)0xe5, (byte)0xcb, (byte)0x5f, (byte)0x4c, (byte)0xc5, (byte)0x18, (byte)0xa7,         (byte)0x58, (byte)0x8a, (byte)0x11, (byte)0xd2, (byte)0xca, (byte)0x7a, (byte)0xef, (byte)0x65,         (byte)0x45, (byte)0xf6, (byte)0xfd, (byte)0xad, (byte)0x27, (byte)0x9f, (byte)0xe6, (byte)0xff,         (byte)0xec, (byte)0x0f, (byte)0x7c, (byte)0x91, (byte)0x4e, (byte)0x81, (byte)0x25, (byte)0x9d,         (byte)0xbb, (byte)0xed, (byte)0x51, (byte)0x6b, (byte)0xd0, (byte)0xe8, (byte)0x8d, (byte)0x98,         (byte)0x50, (byte)0x33, (byte)0x5c, (byte)0xaa, (byte)0x99, (byte)0xf5, (byte)0x89, (byte)0x7e,         (byte)0xa2, (byte)0x71, (byte)0x94, (byte)0xa8, (byte)0x86, (byte)0x46, (byte)0xe9, (byte)0x74,         (byte)0x01, (byte)0xd8, (byte)0x05, (byte)0x4f, (byte)0x32, (byte)0x40, (byte)0xe0, (byte)0xdd,         (byte)0x82, (byte)0xa4, (byte)0xe3, (byte)0xc1, (byte)0x14, (byte)0x13, (byte)0xb6, (byte)0xdb,         (byte)0xf3, (byte)0x23, (byte)0xe1, (byte)0xde, (byte)0x4d, (byte)0x84, (byte)0xc9, (byte)0x5e,         (byte)0xfe, (byte)0x8e, (byte)0xeb, (byte)0x56, (byte)0x83, (byte)0x00, (byte)0x6d, (byte)0x62,         (byte)0xf4, (byte)0xea, (byte)0x15, (byte)0xcc, (byte)0x1a, (byte)0x76, (byte)0x17, (byte)0xf1,         (byte)0x10, (byte)0x8c, (byte)0x73, (byte)0x31, (byte)0xb9, (byte)0x02, (byte)0x54, (byte)0x6f,         (byte)0x92, (byte)0x79, (byte)0x19, (byte)0x22, (byte)0x8b, (byte)0x93, (byte)0xe4, (byte)0xb8,         (byte)0x7b, (byte)0x9b, (byte)0xce, (byte)0x8f, (byte)0x48, (byte)0xd3, (byte)0xd1, (byte)0x0b, };    static long LONG_TEN = 100000000000000L;        int E = 2;        // 額外的循環數量E    int N;            // 分組長度N    int P;            // 基於長度N的完美長度。    int round;        // 用於加密的輪數(對應擴散階段的數量)。    byte[][] KX;    // 用於加密的子密匙(X), 每一輪的密匙都不相同。    byte[][] KY;    // 用於加密的子密匙(Y), 每一輪的密匙都不相同。    // @formatter:on    public CryptoDemo(int keySize) { // keySize:byte        N = keySize;        int G = (int) Math.ceil(Math.log(N) / Math.log(2)); // 計算以2為底N的對數,並向上取整        P = 1 << G; // P=2的G次方        round = G + E;        KX = new byte[round][];        KY = new byte[round][];    }    /**    * 生成子密匙, 通過擴散算法使得原密匙的每一個密匙都影響其它任何一個密匙。    * <p>    * 每個周期完成後,將本周的輸出作為下一個周期的輸入再計運算元密匙。共需round個周期。    * </p>    *     * @param kx    *            原始密匙X    * @param ky    *            原始密匙Y    */    public void init(byte[] kx, byte[] ky) {        for (int i = 0; i < round; i++) {            init(kx, ky, i);        }    }    Function FKx = new XKey(); // 用於生成子密匙的函式X    Function FKy = new YKey(); // 用於生成子密匙的函式Y    private void init(byte[] kx, byte[] ky, int index) {        int l = 0;        for (int i = 1; i <= round; i++) {            for (int r = 0; r < N; r++) {                ky[r] = (byte) (FKy.call(kx[l], ky[r]) & 255);                kx[l] = (byte) (FKx.call(kx[l], ky[r]) & 255);                l = (++l) % N;            }            l = P >> i;        }        KX[index] = kx.clone();        KY[index] = ky.clone();    }    /**    * 用於生成子密匙的函式X實現。    *     * @author Angel    *     */    class XKey implements Function {        int A = 11;        int B = 21;        int C = 31;        @Override        public int call(int x, int y, int... values) {            return A * x * x + B * y + C;        }    }    /**    * 用於生成子密匙的函式Y實現。    *     * @author Angel    *     */    class YKey implements Function {        long C = 0x6180339887L;        @Override        public int call(int x, int y, int... values) {            double a = Math.sin(x);            double b = Math.cos(y);            long v = (long) ((a + b) * LONG_TEN + C);            return (int) (v & 0xffffffff);        }    }    // ----------------------------------------------------------------------------    Function Ex = new XEncrypt(); // 用於加密進行擴散運算的函式X    Function Ey = new YEncrypt(); // 用於加密進行擴散運算的函式Y    /**    * 加密明文。次方法只加密一組數據,X,Y的長度為N。    *     * @param X    *            明文X    * @param Y    *            明文Y    */    public void encrypt(byte[] X, byte[] Y) {        int x = 0;        for (int i = 1, k = 0; i <= round; i++, k++) {            for (int y = 0; y < N; y++) {                Y[y] = (byte) Ey.call(X[x], Y[y], KY[k][y]);                X[x] = (byte) Ex.call(X[x], Y[y], KX[k][y]); // KX[k][x]                // 不建議使用%運算                // 當N&(N-1)=0時,可使用&運算,即N=2的j次方(j>0,且j為整數)                x = (++x) % N; // x = (++x) & (N-1);            }            x = P >> i;        }    }    /**    * 用於加密算法的函式X實現。    *     * @author Angel    *     */    class XEncrypt implements Function {        /**        * 由於java中byte的值域為[-128,127],因此需要將運算後的值加128以改變值域為[0,255](余同)。        *         * <p>        * 此處為行方便,特將key以其他參數的第0位傳入(余同)。        * </p>        */        @Override        public int call(int x, int y, int... values) {            // values[0] is key            return S[(x ^ values[0]) + 128] ^ y;        }    }    /**    * 用於加密算法的函式Y實現。    *     * @author Angel    *     */    class YEncrypt implements Function {        @Override        public int call(int x, int y, int... values) {            // values[0] is key            return S[(y ^ values[0]) + 128] ^ x;        }    }    // ------------------------------------------------------------------------    Function Dx = new XDecrypt(); // 用於解密進行擴散運算的函式X    Function Dy = new YDecrypt(); // 用於解密進行擴散運算的函式Y    /**    * 解密密文,次方法只解密一組數據,X,Y的長度為N。    *     * @param X    *            密文X,對應加密後所輸出的X    * @param Y    *            密文Y,對應加密後所輸出的Y    */    public void decrypt(byte[] X, byte[] Y) {        int x = 0;        int k = round - 1;        for (int i = 0; i < round; i++, k--) {            for (int y = 0; y < N; y++) {                X[x] = (byte) Dx.call(X[x], Y[y], KX[k][y]); // KX[k][x]                Y[y] = (byte) Dy.call(X[x], Y[y], KY[k][y]);                x = (++x) % N; // x=(++x)&(N-1); and N&(N-1)=0            }            x = (1 << i) % P; // x=(1<<i)&(P-1); and P&(P-1)=0        }    }    /**    * 用於解密算法的函式X實現。    *     * @author Angel    *     */    class XDecrypt implements Function {        @Override        public int call(int x, int y, int... values) {            // values[0] is key            return _S[(x ^ y) + 128] ^ values[0];        }    }    /**    * 用於解密算法的函式Y實現。    *     * @author Angel    *     */    class YDecrypt implements Function {        @Override        public int call(int x, int y, int... values) {            // values[0] is key            return _S[(x ^ y) + 128] ^ values[0];        }    }    // ---------------------------------------------------------------------------    static interface Function {        int call(int x, int y, int... values);    }    static void print(byte[] array) {        for (byte b : array) {            String s = Integer.toHexString(b & 0xff);            if (s.length() == 1) {                s = '0' + s;            }            System.out.print(s + ", ");        }    }    // --------------------------------------------------------------------------    /**    * 微變加密測試, 每次加密只需改變原輸入的一個元素(可以是密匙或者明文)。    * 不建議使用弱密匙,當所有密匙X的元素相等且所有密匙Y的元素都相等時為弱密匙,即:    * <p>    * KX[0]=KX[1]=KX[2]=...=KX[n-1]; KY[0]=KY[1]=KY[2]=...=KY[n-1];    * </P>    */    public static void microChangeTest() {        String line = "-------------------------------------------------------------------------------";        int length = 9;        byte[] KX = { 1, 1, 1, 1, 1, 1, 1, 1, 2 }; // 密匙X(不建議全部相等)        byte[] KY = { 1, 1, 1, 1, 1, 1, 1, 1, 2 }; // 密匙Y(不建議全部相等)        byte[] MX = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }; // 明文X        byte[] MY = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }; // 明文Y        CryptoDemo demo = new CryptoDemo(length);        for (int i = 0; i < 256; i++) {            demo.init(KX, KY); // 初始化密匙            byte[] TX = MX.clone();            byte[] TY = MY.clone();            System.out.print("明     文:");            print(TX);            print(TY);            System.out.println();            demo.encrypt(TX, TY);            System.out.print("加密後:");            print(TX);            print(TY);            System.out.println();            byte[] CX = TX.clone();            byte[] CY = TY.clone();            demo.decrypt(CX, CY);            System.out.print("解密後:");            print(CX);            print(CY);            System.out.println();            MX[0]++; // 更改原數據            System.out.println(line);        }    }    public static void main(String[] args) {        microChangeTest();    }}

相關詞條

熱門詞條

聯絡我們